Example #1
0
 def _receipt(self, node):
     self._write(
         Node("receipt",
              type="read",
              to=node["from"],
              id=node["id"],
              t=utils.timestamp()))
Example #2
0
    def connect(self):
        self.reader = Reader()
        self.writer = Writer()

        self._connect()

        buf = self.writer.start_stream(self.SERVER, "%s-%s-%d" % (
            PROTOCOL_DEVICE, PROTOCOL_VERSION, PORT))
        self._write(buf)

        # Send features node
        features = Node("stream:features")
        features.add(Node("readreceipts"))
        features.add(Node("groups_v2"))
        features.add(Node("privacy"))
        features.add(Node("presence"))
        self._write(features)

        # Send auth node
        auth = Node("auth", mechanism="WAUTH-2", user=self.number)

        if self.auth_blob:
            encryption = AuthBlobEncryption(self.secret, self.auth_blob)
            logger.debug(
                "Session Keys (re-using auth challenge): %s",
                [key.encode("hex") for key in encryption.keys])

            self.reader.decrypt = encryption.decrypt

            # From WhatsAPI. It does not encrypt the data, but generates a MAC
            # based on the keys.
            data = "%s%s%s" % (self.number, self.auth_blob, utils.timestamp())
            auth.data = encryption.encrypt("", False) + data

        self._write(auth)

        def on_success(node):
            self.auth_blob = node.data
            self.account_info = node.attributes

            if node["status"] == "expired":
                self._disconnect()
                raise LoginError("Account marked as expired.")

            self._write(Node("presence", name=self.nickname))

        def on_failure(node):
            self._disconnect()
            raise LoginError("Incorrect number and/or secret.")

        # Wait for either success, or failure
        self.register_callback_and_wait(
            LoginSuccessCallback(on_success),
            LoginFailedCallback(on_failure))
Example #3
0
    def connect(self):
        self.reader = Reader()
        self.writer = Writer()

        self._connect()

        buf = self.writer.start_stream(
            self.SERVER,
            "%s-%s-%d" % (PROTOCOL_DEVICE, PROTOCOL_VERSION, PORT))
        self._write(buf)

        # Send features node
        features = Node("stream:features")
        features.add(Node("readreceipts"))
        features.add(Node("groups_v2"))
        features.add(Node("privacy"))
        features.add(Node("presence"))
        self._write(features)

        # Send auth node
        auth = Node("auth", mechanism="WAUTH-2", user=self.number)

        if self.auth_blob:
            encryption = AuthBlobEncryption(self.secret, self.auth_blob)
            logger.debug("Session Keys (re-using auth challenge): %s",
                         [key.encode("hex") for key in encryption.keys])

            self.reader.decrypt = encryption.decrypt

            # From WhatsAPI. It does not encrypt the data, but generates a MAC
            # based on the keys.
            data = "%s%s%s" % (self.number, self.auth_blob, utils.timestamp())
            auth.data = encryption.encrypt("", False) + data

        self._write(auth)

        def on_success(node):
            self.auth_blob = node.data
            self.account_info = node.attributes

            if node["status"] == "expired":
                self._disconnect()
                raise LoginError("Account marked as expired.")

            self._write(Node("presence", name=self.nickname))

        def on_failure(node):
            self._disconnect()
            raise LoginError("Incorrect number and/or secret.")

        # Wait for either success, or failure
        self.register_callback_and_wait(LoginSuccessCallback(on_success),
                                        LoginFailedCallback(on_failure))
Example #4
0
    def _challenge(self, node):
        encryption = Encryption(self.secret, node.data)
        logger.debug("Session Keys: %s",
                     [key.encode("hex") for key in encryption.keys])

        self.writer.encrypt = encryption.encrypt
        self.reader.decrypt = encryption.decrypt

        data = "%s%s%s" % (self.number, node.data, utils.timestamp())
        response = Node("response", data=encryption.encrypt(data, False))

        self._write(response, encrypt=False)
        self._incoming()
Example #5
0
    def _message(self, to, node, group=False):
        msgid = self._msgid("message")
        to = self._jid(to)

        x = Node("x", xmlns="jabber:x:event", children=Node("server"))
        notify = Node("notify", xmlns="urn:xmpp:whatsapp", name=self.nickname)
        request = Node("request", xmlns="urn:xmpp:receipts")

        message = Node(
            "message", to=to, type="text", id=msgid, t=utils.timestamp(),
            children=[x, notify, request, node])

        return msgid, message
Example #6
0
    def _challenge(self, node):
        encryption = Encryption(self.secret, node.data)
        logger.debug(
            "Session Keys: %s", [key.encode("hex") for key in encryption.keys])

        self.writer.encrypt = encryption.encrypt
        self.reader.decrypt = encryption.decrypt

        data = "%s%s%s" % (self.number, node.data, utils.timestamp())
        response = Node("response", data=encryption.encrypt(data, False))

        self._write(response, encrypt=False)
        self._incoming()
Example #7
0
    def _message(self, to, node, group=False):
        msgid = self._msgid("message")
        to = self._jid(to)

        x = Node("x", xmlns="jabber:x:event", children=Node("server"))
        notify = Node("notify", xmlns="urn:xmpp:whatsapp", name=self.nickname)
        request = Node("request", xmlns="urn:xmpp:receipts")

        message = Node("message",
                       to=to,
                       type="text",
                       id=msgid,
                       t=utils.timestamp(),
                       children=[x, notify, request, node])

        return msgid, message
Example #8
0
    def _msgid(self, prefix):
        """
        Generate a unique message ID.
        """

        return "%s-%s-%d" % (prefix, utils.timestamp(), self.counter)
Example #9
0
 def _receipt(self, node):
     self._write(Node(
         "receipt", type="read", to=node["from"], id=node["id"],
         t=utils.timestamp()))
Example #10
0
    def _msgid(self, prefix):
        """
        Generate a unique message ID.
        """

        return "%s-%s-%d" % (prefix, utils.timestamp(), self.counter)