示例#1
0
 public function Process()
 {
     if ($this->node->getChild("query") != null) {
         if (isset($this->parent->getNodeId()['privacy']) && $this->parent->getNodeId()['privacy'] == $this->node->getAttribute('id')) {
             $listChild = $this->node->getChild(0)->getChild(0);
             foreach ($listChild->getChildren() as $child) {
                 $blockedJids[] = $child->getAttribute('value');
             }
             $this->parent->eventManager()->fire("onGetPrivacyBlockedList", array($this->phoneNumber, $blockedJids));
             return;
         }
     }
     if ($this->node->getAttribute('type') == "get" && $this->node->getAttribute('xmlns') == "urn:xmpp:ping") {
         $this->parent->eventManager()->fire("onPing", array($this->phoneNumber, $this->node->getAttribute('id')));
         $this->parent->sendPong($this->node->getAttribute('id'));
     }
     if ($this->node->getChild("sync") != null) {
         //sync result
         $sync = $this->node->getChild('sync');
         $existing = $sync->getChild("in");
         $nonexisting = $sync->getChild("out");
         //process existing first
         $existingUsers = array();
         if (!empty($existing)) {
             foreach ($existing->getChildren() as $child) {
                 $existingUsers[$child->getData()] = $child->getAttribute("jid");
             }
         }
         //now process failed numbers
         $failedNumbers = array();
         if (!empty($nonexisting)) {
             foreach ($nonexisting->getChildren() as $child) {
                 $failedNumbers[] = str_replace('+', '', $child->getData());
             }
         }
         $index = $sync->getAttribute("index");
         $result = new SyncResult($index, $sync->getAttribute("sid"), $existingUsers, $failedNumbers);
         $this->parent->eventManager()->fire("onGetSyncResult", array($result));
     }
     if ($this->node->getChild("props") != null) {
         //server properties
         $props = array();
         foreach ($this->node->getChild(0)->getChildren() as $child) {
             $props[$child->getAttribute("name")] = $child->getAttribute("value");
         }
         $this->parent->eventManager()->fire("onGetServerProperties", array($this->phoneNumber, $this->node->getChild(0)->getAttribute("version"), $props));
     }
     if ($this->node->getChild("picture") != null) {
         $this->parent->eventManager()->fire("onGetProfilePicture", array($this->phoneNumber, $this->node->getAttribute("from"), $this->node->getChild("picture")->getAttribute("type"), $this->node->getChild("picture")->getData()));
     }
     if ($this->node->getChild("media") != null || $this->node->getChild("duplicate") != null) {
         $this->parent->processUploadResponse($this->node);
     }
     if (strpos($this->node->getAttribute("from"), Constants::WHATSAPP_GROUP_SERVER) !== false) {
         //There are multiple types of Group reponses. Also a valid group response can have NO children.
         //Events fired depend on text in the ID field.
         $groupList = array();
         $groupNodes = array();
         if ($this->node->getChild(0) != null && $this->node->getChild(0)->getChildren() != null) {
             foreach ($this->node->getChild(0)->getChildren() as $child) {
                 $groupList[] = $child->getAttributes();
                 $groupNodes[] = $child;
             }
         }
         if (isset($this->parent->getNodeId()['groupcreate']) && $this->parent->getNodeId()['groupcreate'] == $this->node->getAttribute('id')) {
             $this->parent->setGroupId($this->node->getChild(0)->getAttribute('id'));
             $this->parent->eventManager()->fire("onGroupsChatCreate", array($this->phoneNumber, $this->node->getChild(0)->getAttribute('id')));
         }
         if (isset($this->parent->getNodeId()['leavegroup']) && $this->parent->getNodeId()['leavegroup'] == $this->node->getAttribute('id')) {
             $this->parent->setGroupId($this->node->getChild(0)->getChild(0)->getAttribute('id'));
             $this->parent->eventManager()->fire("onGroupsChatEnd", array($this->phoneNumber, $this->node->getChild(0)->getChild(0)->getAttribute('id')));
         }
         if (isset($this->parent->getNodeId()['getgroups']) && $this->parent->getNodeId()['getgroups'] == $this->node->getAttribute('id')) {
             $this->parent->eventManager()->fire("onGetGroups", array($this->phoneNumber, $groupList));
             //getGroups returns a array of nodes which are exactly the same as from getGroupV2Info
             //so lets call this event, we have all data at hand, no need to call getGroupV2Info for every
             //group we are interested
             foreach ($groupNodes as $groupNode) {
                 $this->handleGroupV2InfoResponse($groupNode, true);
             }
         }
         if (isset($this->parent->getNodeId()['get_groupv2_info']) && $this->parent->getNodeId()['get_groupv2_info'] == $this->node->getAttribute('id')) {
             $groupChild = $this->node->getChild(0);
             if ($groupChild != null) {
                 $this->handleGroupV2InfoResponse($groupChild);
             }
         }
     }
     if (isset($this->parent->getNodeId()['get_lists']) && $this->parent->getNodeId()['get_lists'] == $this->node->getAttribute('id')) {
         $broadcastLists = array();
         if ($this->node->getChild(0) != null) {
             $childArray = $this->node->getChildren();
             foreach ($childArray as $list) {
                 if ($list->getChildren() != null) {
                     foreach ($list->getChildren() as $sublist) {
                         $id = $sublist->getAttribute("id");
                         $name = $sublist->getAttribute("name");
                         $broadcastLists[$id]['name'] = $name;
                         $recipients = array();
                         foreach ($sublist->getChildren() as $recipient) {
                             array_push($recipients, $recipient->getAttribute('jid'));
                         }
                         $broadcastLists[$id]['recipients'] = $recipients;
                     }
                 }
             }
         }
         $this->parent->eventManager()->fire("onGetBroadcastLists", array($this->phoneNumber, $broadcastLists));
     }
     if ($this->node->getChild("pricing") != null) {
         $this->parent->eventManager()->fire("onGetServicePricing", array($this->phoneNumber, $this->node->getChild(0)->getAttribute("price"), $this->node->getChild(0)->getAttribute("cost"), $this->node->getChild(0)->getAttribute("currency"), $this->node->getChild(0)->getAttribute("expiration")));
     }
     if ($this->node->getChild("extend") != null) {
         $this->parent->eventManager()->fire("onGetExtendAccount", array($this->phoneNumber, $this->node->getChild("account")->getAttribute("kind"), $this->node->getChild("account")->getAttribute("status"), $this->node->getChild("account")->getAttribute("creation"), $this->node->getChild("account")->getAttribute("expiration")));
     }
     if ($this->node->getChild("normalize") != null) {
         $this->parent->eventManager()->fire("onGetNormalizedJid", array($this->phoneNumber, $this->node->getChild(0)->getAttribute("result")));
     }
     if ($this->node->getChild("status") != null) {
         $child = $this->node->getChild("status");
         $childs = $child->getChildren();
         if (isset($childs) && !is_null($childs)) {
             foreach ($childs as $status) {
                 $this->parent->eventManager()->fire("onGetStatus", array($this->phoneNumber, $status->getAttribute("jid"), "requested", $this->node->getAttribute("id"), $status->getAttribute("t"), $status->getData()));
             }
         }
     }
     if ($this->node->getAttribute('type') == "error" && $this->node->getChild("error") != null) {
         $errorType = null;
         $this->parent->logFile('error', 'Iq error with {id} id', array('id' => $this->node->getAttribute('id')));
         foreach ($this->parent->getNodeId() as $type => $nodeID) {
             if ($nodeID == $this->node->getAttribute('id')) {
                 $errorType = $type;
                 break;
             }
         }
         $nodeIds = $this->parent->getNodeId();
         if (isset($nodeIds['sendcipherKeys']) && isset($nodeIds['sendcipherKeys']) == $this->node->getAttribute('id') && $this->node->getChild("error")->getAttribute('code') == "406") {
             $this->parent->sendSetPreKeys();
         }
         $this->parent->eventManager()->fire("onGetError", array($this->phoneNumber, $this->node->getAttribute('from'), $this->node->getAttribute('id'), $this->node->getChild(0), $errorType));
     }
     if (isset($this->parent->getNodeId()['cipherKeys']) && $this->parent->getNodeId()['cipherKeys'] == $this->node->getAttribute('id')) {
         $users = $this->node->getChild(0)->getChildren();
         foreach ($users as $user) {
             $jid = $user->getAttribute("jid");
             $registrationId = deAdjustId($user->getChild('registration')->getData());
             $identityKey = new IdentityKey(new DjbECPublicKey($user->getChild('identity')->getData()));
             $signedPreKeyId = deAdjustId($user->getChild('skey')->getChild('id')->getData());
             $signedPreKeyPub = new DjbECPublicKey($user->getChild('skey')->getChild('value')->getData());
             $signedPreKeySig = $user->getChild('skey')->getChild('signature')->getData();
             $preKeyId = deAdjustId($user->getChild('key')->getChild('id')->getData());
             $preKeyPublic = new DjbECPublicKey($user->getChild('key')->getChild('value')->getData());
             $preKeyBundle = new PreKeyBundle($registrationId, 1, $preKeyId, $preKeyPublic, $signedPreKeyId, $signedPreKeyPub, $signedPreKeySig, $identityKey);
             $sessionBuilder = new SessionBuilder($this->parent->getAxolotlStore(), $this->parent->getAxolotlStore(), $this->parent->getAxolotlStore(), $this->parent->getAxolotlStore(), ExtractNumber($jid), 1);
             $sessionBuilder->processPreKeyBundle($preKeyBundle);
             if (isset($this->parent->getPendingNodes()[ExtractNumber($jid)])) {
                 foreach ($this->parent->getPendingNodes()[ExtractNumber($jid)] as $pendingNode) {
                     $msgHandler = new MessageHandler($this->parent, $pendingNode);
                     $msgHandler->Process();
                 }
                 unset($this->parent->getPendingNodes()[ExtractNumber($jid)]);
             }
             $this->parent->sendPendingMessages($jid);
         }
     }
 }
 public function test_basicKeyExchange()
 {
     $aliceStore = new InMemoryAxolotlStore();
     $aliceSessionBuilder = new SessionBuilder($aliceStore, $aliceStore, $aliceStore, $aliceStore, self::BOB_RECIPIENT_ID, 1);
     $bobStore = new InMemoryAxolotlStore();
     $bobSessionBuilder = new SessionBuilder($bobStore, $bobStore, $bobStore, $bobStore, self::ALICE_RECIPIENT_ID, 1);
     $aliceKeyExchangeMessage = $aliceSessionBuilder->processInitKeyExchangeMessage();
     $this->assertTrue($aliceKeyExchangeMessage != null);
     $aliceKeyExchangeMessageBytes = $aliceKeyExchangeMessage->serialize();
     $bobKeyExchangeMessage = $bobSessionBuilder->processKeyExchangeMessage(new KeyExchangeMessage(null, null, null, null, null, null, null, $aliceKeyExchangeMessageBytes));
     $this->assertTrue($bobKeyExchangeMessage != null);
     define("TEST", true);
     $bobKeyExchangeMessageBytes = $bobKeyExchangeMessage->serialize();
     $response = $aliceSessionBuilder->processKeyExchangeMessage(new KeyExchangeMessage(null, null, null, null, null, null, null, $bobKeyExchangeMessageBytes));
     $this->assertTrue($response == null);
     $this->assertTrue($aliceStore->containsSession(self::BOB_RECIPIENT_ID, 1));
     $this->assertTrue($bobStore->containsSession(self::ALICE_RECIPIENT_ID, 1));
     $this->runInteraction($aliceStore, $bobStore);
     $aliceStore = new InMemoryAxolotlStore();
     $aliceSessionBuilder = new SessionBuilder($aliceStore, $aliceStore, $aliceStore, $aliceStore, self::BOB_RECIPIENT_ID, 1);
     $aliceKeyExchangeMessage = $aliceSessionBuilder->processInitKeyExchangeMessage();
     try {
         $bobKeyExchangeMessage = $bobSessionBuilder->processKeyExchangeMessage($aliceKeyExchangeMessage);
         throw new AssertionError("This identity shouldn't be trusted!");
     } catch (UntrustedIdentityException $ex) {
         $bobStore->saveIdentity(self::ALICE_RECIPIENT_ID, $aliceKeyExchangeMessage->getIdentityKey());
     }
     $bobKeyExchangeMessage = $bobSessionBuilder->processKeyExchangeMessage($aliceKeyExchangeMessage);
     $this->assertTrue($aliceSessionBuilder->processKeyExchangeMessage($bobKeyExchangeMessage) == null);
     self . runInteraction($aliceStore, $bobStore);
 }