Beispiel #1
0
 public function __construct(\WhatsProt $parent, \ProtocolNode $node)
 {
     $this->node = $node;
     $this->type = $node->getAttribute('type');
     $this->parent = $parent;
     $this->phoneNumber = $this->parent->getMyNumber();
 }
 /**
  * @param ProtocolNode $node
  */
 public function process($node)
 {
     if ($node->getAttribute("type") == 'text') {
         $text = $node->getChild('body');
         $text = $text->getData();
         if ($text && ($text == "5" || trim($text) == "5")) {
             $this->wp->sendMessageImage($this->target, "https://s3.amazonaws.com/f.cl.ly/items/2F3U0A1K2o051q1q1e1G/baby-nailed-it.jpg");
             $this->wp->sendMessage($this->target, "Congratulations you guessed the right number!");
         } elseif (ctype_digit($text)) {
             if ((int) $text != "5") {
                 $this->wp->sendMessage($this->target, "I'm sorry, try again!");
             }
         }
         $text = $node->getChild('body');
         $text = $text->getData();
         $notify = $node->getAttribute("notify");
         echo "\n- " . $notify . ": " . $text . "    " . date('H:i') . "\n";
     }
 }
Beispiel #3
0
 /**
  * Tell the server we received the message.
  *
  * @param ProtocolNode $msg
  *   The ProtocolTreeNode that contains the message.
  */
 protected function sendMessageReceived($msg, $type = null)
 {
     if ($type) {
         $messageHash["type"] = $type;
     }
     $messageHash = array();
     $messageHash["to"] = $msg->getAttribute("from");
     $messageHash["id"] = $msg->getAttribute("id");
     $messageNode = new ProtocolNode("receipt", $messageHash, null, null);
     $this->sendNode($messageNode);
     $this->eventManager()->fireSendMessageReceived($this->phoneNumber, $msg->getAttribute("id"), $msg->getAttribute("from"), $type);
 }
 /**
  * @param ProtocolNode $groupNode
  * @param mixed        $fromGetGroups
  */
 protected function handleGroupV2InfoResponse(ProtocolNode $groupNode, $fromGetGroups = false)
 {
     $creator = $groupNode->getAttribute('creator');
     $creation = $groupNode->getAttribute('creation');
     $subject = $groupNode->getAttribute('subject');
     $groupID = $groupNode->getAttribute('id');
     $participants = array();
     $admins = array();
     if ($groupNode->getChild(0) != null) {
         foreach ($groupNode->getChildren() as $child) {
             $participants[] = $child->getAttribute('jid');
             if ($child->getAttribute('type') == "admin") {
                 $admins[] = $child->getAttribute('jid');
             }
         }
     }
     $this->eventManager()->fire("onGetGroupV2Info", array($this->phoneNumber, $groupID, $creator, $creation, $subject, $participants, $admins, $fromGetGroups));
 }
 /**
  * Tell the server we received the message.
  *
  * @param ProtocolNode $msg The ProtocolTreeNode that contains the message.
  * @param string       $type
  * @param string       $participant
  */
 protected function sendMessageReceived($msg, $type = "read", $participant = null)
 {
     $messageHash = array();
     if ($type == "read") {
         $messageHash["type"] = $type;
     }
     if ($participant != null) {
         $messageHash["participant"] = $participant;
     }
     $messageHash["to"] = $msg->getAttribute("from");
     $messageHash["id"] = $msg->getAttribute("id");
     $messageHash["t"] = time();
     $messageNode = new ProtocolNode("receipt", $messageHash, null, null);
     $this->sendNode($messageNode);
     $this->eventManager()->fire("onSendMessageReceived", array($this->phoneNumber, $msg->getAttribute("id"), $msg->getAttribute("from"), $type));
 }
 public function process(\ProtocolNode $node)
 {
     $text = $node->getChild('body');
     $text = $text->getData();
     $notify = $node->getAttribute('notify');
     echo "\n- " . $notify . ': ' . $text . '    ' . date('H:i') . "\n";
 }
Beispiel #7
0
 /**
  * Tell the server we received the message.
  *
  * @param ProtocolNode $node The ProtocolTreeNode that contains the message.
  * @param string       $type
  * @param string       $participant
  * @param string       $callId
  */
 public function sendReceipt($node, $type = "read", $participant = null, $callId = null)
 {
     $messageHash = array();
     if ($type == "read") {
         $messageHash["type"] = $type;
     }
     if ($participant != null) {
         $messageHash["participant"] = $participant;
     }
     $messageHash["to"] = $node->getAttribute("from");
     $messageHash["id"] = $node->getAttribute("id");
     $messageHash["t"] = $node->getAttribute("t");
     if ($callId != null) {
         $offerNode = new ProtocolNode("offer", array("call-id" => $callId), null, null);
         $messageNode = new ProtocolNode("receipt", $messageHash, array($offerNode), null);
     } else {
         $messageNode = new ProtocolNode("receipt", $messageHash, null, null);
     }
     $this->sendNode($messageNode);
     $this->eventManager()->fire("onSendMessageReceived", array($this->phoneNumber, $node->getAttribute("id"), $node->getAttribute("from"), $type));
 }
 /**
  * @param ProtocolNode $node
  */
 public function process($node)
 {
     // Example of process function, you have to guess a number (psss it's 5)
     // If you guess it right you get a gift
     if ($node->getAttribute('type') == 'text') {
         $text = $node->getChild('body');
         $text = $text->getData();
         if ($text && ($text == '5' || trim($text) == '5')) {
             $this->wp->sendMessageImage($this->target, 'https://s3.amazonaws.com/f.cl.ly/items/2F3U0A1K2o051q1q1e1G/baby-nailed-it.jpg');
             $this->wp->sendMessage($this->target, 'Congratulations you guessed the right number!');
         } elseif (ctype_digit($text)) {
             if ((int) $text != '5') {
                 $this->wp->sendMessage($this->target, "I'm sorry, try again!");
             }
         }
         $text = $node->getChild('body');
         $text = $text->getData();
         $notify = $node->getAttribute('notify');
         echo "\n- " . $notify . ': ' . $text . '    ' . date('H:i') . "\n";
     }
 }
Beispiel #9
0
 /**
  * Tell the server we received the message.
  *
  * @param ProtocolNode $node        The ProtocolTreeNode that contains the message.
  * @param string       $type
  * @param string       $participant
  * @param string       $callId
  */
 public function sendReceipt($node, $type = 'read', $participant = null, $callId = null)
 {
     $messageHash = [];
     if ($type == 'read') {
         $messageHash['type'] = $type;
     }
     if ($participant != null) {
         $messageHash['participant'] = $participant;
     }
     $messageHash['to'] = $node->getAttribute('from');
     $messageHash['id'] = $node->getAttribute('id');
     $messageHash['t'] = $node->getAttribute('t');
     if ($callId != null) {
         $offerNode = new ProtocolNode('offer', ['call-id' => $callId], null, null);
         $messageNode = new ProtocolNode('receipt', $messageHash, [$offerNode], null);
     } else {
         $messageNode = new ProtocolNode('receipt', $messageHash, null, null);
     }
     $this->sendNode($messageNode);
     $this->eventManager()->fire('onSendMessageReceived', [$this->phoneNumber, $node->getAttribute('id'), $node->getAttribute('from'), $type]);
 }
Beispiel #10
0
 /**
  * Tell the server we received the message.
  *
  * @param ProtocolNode $msg
  *   The ProtocolTreeNode that contains the message.
  */
 protected function sendMessageReceived($msg)
 {
     $requestNode = $msg->getChild("request");
     $receivedNode = $msg->getChild("received");
     if ($requestNode != null || $receivedNode != null) {
         $receivedHash = array();
         $receivedHash["xmlns"] = "urn:xmpp:receipts";
         $response = "received";
         if ($receivedNode != null) {
             $response = "ack";
         }
         $receivedNode = new ProtocolNode($response, $receivedHash, null, "");
         $messageHash = array();
         $messageHash["to"] = $msg->getAttribute("from");
         $messageHash["type"] = "chat";
         $messageHash["id"] = $msg->getAttribute("id");
         $messageHash["t"] = time();
         $messageNode = new ProtocolNode("message", $messageHash, array($receivedNode), "");
         $this->sendNode($messageNode);
         $this->eventManager()->fire('onSendMessageReceived', array($this->phoneNumber, $messageHash["t"], $msg->getAttribute("from")));
     }
 }
Beispiel #11
0
 protected function processEncryptedNode(ProtocolNode $node)
 {
     if ($this->parent->getAxolotlStore() == null) {
         return;
     }
     //is a chat encrypted message
     $from = $node->getAttribute('from');
     if (strpos($from, Constants::WHATSAPP_SERVER) !== false) {
         $author = ExtractNumber($node->getAttribute('from'));
         $version = $node->getChild(0)->getAttribute('v');
         $encType = $node->getChild(0)->getAttribute('type');
         $encMsg = $node->getChild('enc')->getData();
         if (!$this->parent->getAxolotlStore()->containsSession($author, 1)) {
             //we don't have the session to decrypt, save it in pending and process it later
             $this->parent->addPendingNode($node);
             $this->parent->logFile('info', 'Requesting cipher keys from {from}', ['from' => $author]);
             $this->parent->sendGetCipherKeysFromUser($author);
         } else {
             //decrypt the message with the session
             if ($node->getChild('enc')->getAttribute('count') == '') {
                 $this->parent->setRetryCounter($node->getAttribute('id'), 1);
             }
             if ($version == '2') {
                 if (!in_array($author, $this->parent->getv2Jids())) {
                     $this->parent->setv2Jids($author);
                 }
             }
             $plaintext = $this->decryptMessage($from, $encMsg, $encType, $node->getAttribute('id'), $node->getAttribute('t'));
             //$plaintext ="A";
             if ($plaintext === false) {
                 $this->parent->sendRetry($this->node, $from, $node->getAttribute('id'), $node->getAttribute('t'));
                 $this->parent->logFile('info', 'Couldn\'t decrypt message with {id} id from {from}. Retrying...', ['id' => $node->getAttribute('id'), 'from' => ExtractNumber($from)]);
                 return $node;
                 // could not decrypt
             }
             if (isset($this->parent->retryNodes[$node->getAttribute('id')])) {
                 unset($this->parent->retryNodes[$node->getAttribute('id')]);
             }
             if (isset($this->parent->retryCounters[$node->getAttribute('id')])) {
                 unset($this->parent->retryCounters[$node->getAttribute('id')]);
             }
             switch ($node->getAttribute('type')) {
                 case 'text':
                     $node->addChild(new ProtocolNode('body', null, null, $plaintext));
                     break;
                 case 'media':
                     switch ($node->getChild('enc')->getAttribute('mediatype')) {
                         case 'image':
                             $image = new ImageMessage();
                             $image->parseFromString($plaintext);
                             $keys = (new HKDFv3())->deriveSecrets($image->getRefKey(), hex2bin('576861747341707020496d616765204b657973'), 112);
                             $iv = substr($keys, 0, 16);
                             $keys = substr($keys, 16);
                             $parts = str_split($keys, 32);
                             $key = $parts[0];
                             $macKey = $parts[1];
                             $refKey = $parts[2];
                             //should be changed to nice curl, no extra headers :D
                             $file_enc = file_get_contents($image->getUrl());
                             //requires mac check , last 10 chars
                             $mac = substr($file_enc, -10);
                             $cipherImage = substr($file_enc, 0, strlen($file_enc) - 10);
                             $decrypted_image = pkcs5_unpad(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $cipherImage, MCRYPT_MODE_CBC, $iv));
                             //$save_file = tempnam(sys_get_temp_dir(),"WAIMG_");
                             //file_put_contents($save_file,$decrypted_image);
                             $child = new ProtocolNode('media', ['size' => $image->getLength(), 'caption' => $image->getCaption(), 'url' => $image->getUrl(), 'mimetype' => $image->getMimeType(), 'filehash' => bin2hex($image->getSha256()), 'width' => 0, 'height' => 0, 'file' => $decrypted_image, 'type' => 'image'], null, $image->getThumbnail());
                             $node->addChild($child);
                             break;
                     }
                     break;
             }
             $this->parent->logFile('info', 'Decrypted message with {id} from {from}', ['id' => $node->getAttribute('id'), 'from' => ExtractNumber($from)]);
             return $node;
         }
     } else {
         $author = ExtractNumber($node->getAttribute('participant'));
         $group_number = ExtractNumber($node->getAttribute('from'));
         $childs = $node->getChildren();
         foreach ($childs as $child) {
             if ($child->getAttribute('type') == 'pkmsg' || $child->getAttribute('type') == 'msg') {
                 if (!$this->parent->getAxolotlStore()->containsSession($author, 1)) {
                     $this->parent->addPendingNode($node);
                     $this->parent->sendGetCipherKeysFromUser($author);
                     break;
                 } else {
                     //decrypt senderKey and save it
                     $encType = $child->getAttribute('type');
                     $encMsg = $child->getData();
                     $from = $node->getAttribute('participant');
                     $version = $child->getAttribute('v');
                     if ($node->getChild('enc')->getAttribute('count') == '') {
                         $this->parent->setRetryCounter($node->getAttribute('id'), 1);
                     }
                     if ($version == '2') {
                         if (!in_array($author, $this->parent->getv2Jids())) {
                             $this->parent->setv2Jids($author);
                         }
                     }
                     $skip_unpad = $node->getChild('enc', ['type' => 'skmsg']) == null;
                     $senderKeyBytes = $this->decryptMessage($from, $encMsg, $encType, $node->getAttribute('id'), $node->getAttribute('t'), $node->getAttribute('from'), $skip_unpad);
                     if ($senderKeyBytes) {
                         if (!$skip_unpad) {
                             $senderKeyGroupMessage = new SenderKeyGroupMessage();
                             $senderKeyGroupMessage->parseFromString($senderKeyBytes);
                         } else {
                             $senderKeyGroupMessage = new SenderKeyGroupData();
                             try {
                                 $senderKeyGroupMessage->parseFromString($senderKeyBytes);
                             } catch (Exception $ex) {
                                 try {
                                     $senderKeyGroupMessage->parseFromString(substr($senderKeyBytes, 0, -1));
                                 } catch (Exception $ex) {
                                     return $node;
                                 }
                             }
                             $message = $senderKeyGroupMessage->getMessage();
                             $senderKeyGroupMessage = $senderKeyGroupMessage->getSenderKey();
                         }
                         $senderKey = new SenderKeyDistributionMessage(null, null, null, null, $senderKeyGroupMessage->getSenderKey());
                         $groupSessionBuilder = new GroupSessionBuilder($this->parent->axolotlStore);
                         $groupSessionBuilder->processSender($group_number . ':' . $author, $senderKey);
                         if (isset($message)) {
                             $this->parent->sendReceipt($node, 'receipt', $this->parent->getJID($this->phoneNumber));
                             $node->addChild(new ProtocolNode('body', null, null, $message));
                         }
                     }
                 }
             } elseif ($child->getAttribute('type') == 'skmsg') {
                 $version = $child->getAttribute('v');
                 if ($version == '2') {
                     if (!in_array($author, $this->parent->v2Jids)) {
                         $this->parent->setv2Jids($author);
                     }
                 }
                 $plaintext = $this->decryptMessage([$group_number, $author], $child->getData(), $child->getAttribute('type'), $node->getAttribute('id'), $node->getAttribute('t'));
                 if (!$plaintext) {
                     $this->parent->sendRetry($this->node, $from, $node->getAttribute('id'), $node->getAttribute('t'), $node->getAttribute('participant'));
                     $this->parent->logFile('info', 'Couldn\'t decrypt group message with {id} id from {from}. Retrying...', ['id' => $node->getAttribute('id'), 'from' => $from]);
                     return $node;
                     // could not decrypt
                 } else {
                     if (isset($this->parent->retryNodes[$node->getAttribute('id')])) {
                         unset($this->parent->retryNodes[$node->getAttribute('id')]);
                     }
                     if (isset($this->parent->retryCounters[$node->getAttribute('id')])) {
                         unset($this->parent->retryCounters[$node->getAttribute('id')]);
                     }
                     $this->parent->logFile('info', 'Decrypted group message with {id} from {from}', ['id' => $node->getAttribute('id'), 'from' => $from]);
                     $this->parent->sendReceipt($node, 'receipt', $this->parent->getJID($this->phoneNumber));
                     $node->addChild(new ProtocolNode('body', null, null, $plaintext));
                 }
             }
         }
     }
 }
 protected function processEncryptedNode(ProtocolNode $node)
 {
     if ($this->parent->getAxolotlStore() == null) {
         return null;
     }
     //is a chat encrypted message
     $from = $node->getAttribute('from');
     if (strpos($from, Constants::WHATSAPP_SERVER) !== false) {
         $author = ExtractNumber($node->getAttribute("from"));
         $version = $node->getChild(0)->getAttribute("v");
         $encType = $node->getChild(0)->getAttribute("type");
         $encMsg = $node->getChild("enc")->getData();
         if (!$this->parent->getAxolotlStore()->containsSession($author, 1)) {
             //we don't have the session to decrypt, save it in pending and process it later
             $this->parent->addPendingNode($node);
             $this->parent->logFile('info', 'Requesting cipher keys from {from}', array('from' => $author));
             $this->parent->sendGetCipherKeysFromUser($author);
         } else {
             //decrypt the message with the session
             if ($node->getChild("enc")->getAttribute('count') == "") {
                 $this->parent->setRetryCounter = 1;
             }
             if ($version == "2") {
                 if (!in_array($author, $this->parent->getv2Jids())) {
                     $this->parent->setv2Jids($author);
                 }
             }
             $plaintext = $this->decryptMessage($from, $encMsg, $encType, $node->getAttribute('id'), $node->getAttribute('t'));
             if (!$plaintext) {
                 $this->parent->sendRetry($from, $node->getAttribute('id'), $node->getAttribute('t'));
                 $this->parent->logFile('info', 'Couldn\'t decrypt message with {id} id from {from}. Retrying...', array('id' => $node->getAttribute('id'), 'from' => ExtractNumber($from)));
                 return $node;
                 // could not decrypt
             }
             switch ($node->getAttribute("type")) {
                 case "text":
                     $node->addChild(new ProtocolNode("body", null, null, $plaintext));
                     break;
                 case "media":
                     switch ($node->getChild("enc")->getAttribute("mediatype")) {
                         case "image":
                             $image = new ImageMessage();
                             $image->parseFromString($plaintext);
                             break;
                     }
                     break;
             }
             $this->parent->logFile('info', 'Decrypted message with {id} from {from}', array('id' => $node->getAttribute('id'), 'from' => ExtractNumber($from)));
             return $node;
         }
     } else {
         $author = ExtractNumber($node->getAttribute("participant"));
         $group_number = ExtractNumber($node->getAttribute("from"));
         $childs = $node->getChildren();
         foreach ($childs as $child) {
             if ($child->getAttribute("type") == "pkmsg" || $child->getAttribute("type") == "msg") {
                 if (!$this->parent->getAxolotlStore()->containsSession($author, 1)) {
                     $this->parent->addPendingNode($node);
                     $this->parent->sendGetCipherKeysFromUser($author);
                     break;
                 } else {
                     //decrypt senderKey and save it
                     $encType = $child->getAttribute("type");
                     $encMsg = $child->getData();
                     $from = $node->getAttribute("participant");
                     $version = $child->getAttribute("v");
                     if ($node->getChild("enc")->getAttribute('count') == "") {
                         $this->parent->retryCounter = 1;
                     }
                     if ($version == "2") {
                         if (!in_array($author, $this->parent->getv2Jids())) {
                             $this->parent->setv2Jids($author);
                         }
                     }
                     $skip_unpad = $node->getChild("enc", ["type" => "skmsg"]) == null;
                     $senderKeyBytes = $this->decryptMessage($from, $encMsg, $encType, $node->getAttribute('id'), $node->getAttribute('t'), $node->getAttribute("from"), $skip_unpad);
                     if ($senderKeyBytes) {
                         if (!$skip_unpad) {
                             $senderKeyGroupMessage = new SenderKeyGroupMessage();
                             $senderKeyGroupMessage->parseFromString($senderKeyBytes);
                         } else {
                             $senderKeyGroupMessage = new SenderKeyGroupData();
                             try {
                                 $senderKeyGroupMessage->parseFromString($senderKeyBytes);
                             } catch (Exception $ex) {
                                 try {
                                     $senderKeyGroupMessage->parseFromString(substr($senderKeyBytes, 0, -1));
                                 } catch (Exception $ex) {
                                     return $node;
                                 }
                             }
                             $message = $senderKeyGroupMessage->getMessage();
                             $senderKeyGroupMessage = $senderKeyGroupMessage->getSenderKey();
                         }
                         $senderKey = new SenderKeyDistributionMessage(null, null, null, null, $senderKeyGroupMessage->getSenderKey());
                         $groupSessionBuilder = new GroupSessionBuilder($this->axolotlStore);
                         $groupSessionBuilder->processSender($group_number . ":" . $author, $senderKey);
                         if (isset($message)) {
                             $this->parent->sendReceipt($node, 'receipt', $this->parent->getJID($this->phoneNumber));
                             $node->addChild(new ProtocolNode("body", null, null, $message));
                         }
                     }
                 }
             } else {
                 if ($child->getAttribute("type") == "skmsg") {
                     $version = $child->getAttribute("v");
                     if ($version == "2") {
                         if (!in_array($author, $this->v2Jids)) {
                             $this->v2Jids[] = $author;
                         }
                     }
                     $plaintext = $this->decryptMessage([$group_number, $author], $child->getData(), $child->getAttribute("type"), $node->getAttribute('id'), $node->getAttribute('t'));
                     if (!$plaintext) {
                         $this->parent->sendRetry($from, $node->getAttribute('id'), $node->getAttribute('t'));
                         $this->parent->logFile('info', 'Couldn\'t decrypt group message with {id} id from {from}. Retrying...', array('id' => $node->getAttribute('id'), 'from' => $from));
                         return $node;
                         // could not decrypt
                     } else {
                         $this->parent->logFile('info', 'Decrypted group message with {id} from {from}', array('id' => $node->getAttribute('id'), 'from' => $from));
                         $this->parent->sendReceipt($node, 'receipt', $this->parent->getJID($this->phoneNumber));
                         $node->addChild(new ProtocolNode("body", null, null, $plaintext));
                     }
                 }
             }
         }
     }
 }
Beispiel #13
0
 public function process(\ProtocolNode $node)
 {
     if ($node->getAttribute('type') == 'text') {
         $text = $node->getChild('body');
         $text = $text->getData();
         $number = ExtractNumber($node->getAttribute('from'));
         $nickname = findNicknameByPhone($number);
         echo "\n- " . $nickname . ': ' . $text . '    ' . date('H:i') . "\n";
     }
 }