Пример #1
0
    def _ping(self):
        msgid = self._msgid()

        message = Node("iq", id=msgid, type="get", to=self.SERVER)
        message.add(Node("ping", xmlns="w:p"))

        self._write(message)
Пример #2
0
    def send_sync(self,
                  numbers,
                  mode="full",
                  context="registration",
                  index=0,
                  last=True):
        msgid = self._msgid("sync")
        sid = (int(time()) + 11644477200) * 10000000

        sync = Node("sync",
                    mode=mode,
                    context=context,
                    sid=str(sid),
                    index=str(index),
                    last="true" if last else "false")
        node = Node("iq",
                    to=self.number + "@" + self.SERVER,
                    type="get",
                    id=msgid,
                    xmlns="urn:xmpp:whatsapp:sync")
        node.add(sync)

        # Add numbers to node
        for number in numbers:
            if number[0] != "+":
                number = "+" + number
            sync.add(Node("user", data=number))

        self._write(node)
Пример #3
0
    def _ping(self):
        msgid = self._msgid()

        message = Node("iq", id=msgid, type="get", to=self.SERVER)
        message.add(Node("ping", xmlns="w:p"))

        self._write(message)
Пример #4
0
    def _received(self, node):
        request = node.child("request")
        if request is None or request["xmlns"] != "urn:xmpp:receipts":
            return

        message = Node("message", to=node["from"], id=node["id"], type="chat")
        message.add(Node("received", xmlns="urn:xmpp:receipts"))

        self._write(message)
Пример #5
0
    def _received(self, node):
        request = node.child("request")
        if request is None or request["xmlns"] != "urn:xmpp:receipts":
            return

        message = Node("message", to=node["from"], id=node["id"], type="chat")
        message.add(Node("received", xmlns="urn:xmpp:receipts"))

        self._write(message)
Пример #6
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))
Пример #7
0
    def last_seen(self, number):
        msgid = self._msgid("lastseen")

        iq = Node("iq", type="get", id=msgid)
        iq["from"] = self.number + "@" + self.SERVER
        iq["to"] = number + "@" + self.SERVER
        iq.add(Node("query", xmlns="jabber:iq:last"))

        self._write(iq)

        def on_iq(node):
            if node["id"] != msgid:
                return
            if node["type"] == "error":
                return StreamError(node.child("error").children[0].name)
            return int(node.child("query")["seconds"])

        callback = Callback("iq", on_iq)
        self.register_callback_and_wait(callback)
Пример #8
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))
Пример #9
0
    def last_seen(self, number):
        msgid = self._msgid("lastseen")

        iq = Node("iq", type="get", id=msgid)
        iq["from"] = self.number + "@" + self.SERVER
        iq["to"] = number + "@" + self.SERVER
        iq.add(Node("query", xmlns="jabber:iq:last"))

        self._write(iq)

        def on_iq(node):
            if node["id"] != msgid:
                return
            if node["type"] == "error":
                return StreamError(node.child("error").children[0].name)
            return int(node.child("query")["seconds"])

        callback = Callback("iq", on_iq)
        self.register_callback_and_wait(callback)
Пример #10
0
    def send_sync(self, numbers, mode="full", context="registration", index=0,
                  last=True):
        msgid = self._msgid("sync")
        sid = (int(time()) + 11644477200) * 10000000

        sync = Node(
            "sync", mode=mode, context=context, sid=str(sid), index=str(index),
            last="true" if last else "false")
        node = Node(
            "iq", to=self.number + "@" + self.SERVER, type="get", id=msgid,
            xmlns="urn:xmpp:whatsapp:sync")
        node.add(sync)

        # Add numbers to node
        for number in numbers:
            if number[0] != "+":
                number = "+" + number
            sync.add(Node("user", data=number))

        self._write(node)
Пример #11
0
    def login(self):
        assert self.socket is None

        self._connect()

        buf = self.writer.start_stream(self.SERVER, self.VERSION)
        self._write(buf)

        features = Node("stream:features")
        features.add(Node("receipt_acks"))
        features.add(Node("w:profile:picture", type="all"))
        features.add(Node("status"))

        # m1.java:48
        features.add(Node("notification", type="participant"))
        features.add(Node("groups"))

        self._write(features)

        auth = Node("auth",
                    xmlns="urn:ietf:params:xml:ns:xmpp-sasl",
                    mechanism="WAUTH-1",
                    user=self.number)
        self._write(auth)

        def on_success(node):
            logger.info("Login attempt successfull")
            self.account_info = node.attributes

            presence = Node("presence")
            presence["name"] = self.nickname
            self._write(presence)

        # Create new callback
        callback = Callback("success", on_success)
        self.register_callback_and_wait(callback)

        # Done
        return self.account_info != None
Пример #12
0
    def login(self):
        assert self.socket is None

        self._connect()

        buf = self.writer.start_stream(self.SERVER, self.VERSION)
        self._write(buf)

        features = Node("stream:features")
        features.add(Node("receipt_acks"))
        features.add(Node("w:profile:picture", type="all"))
        features.add(Node("status"))

        # m1.java:48
        features.add(Node("notification", type="participant"))
        features.add(Node("groups"))

        self._write(features)

        auth = Node("auth", xmlns="urn:ietf:params:xml:ns:xmpp-sasl",
                    mechanism="WAUTH-1", user=self.number)
        self._write(auth)

        def on_success(node):
            logger.info("Login attempt successfull")
            self.account_info = node.attributes

            presence = Node("presence")
            presence["name"] = self.nickname
            self._write(presence)

        # Create new callback
        callback = Callback("success", on_success)
        self.register_callback_and_wait(callback)

        # Done
        return self.account_info != None
Пример #13
0
    def _message(self, to, node, group=False):
        msgid = self._msgid()

        message = Node("message", type="chat", id=msgid)
        message["to"] = to + "@" + (self.GROUPHOST if group else self.SERVER)

        x = Node("x", xmlns="jabber:x:event")
        x.add(Node("server"))

        message.add(x)
        message.add(node)

        return msgid, message
Пример #14
0
    def _message(self, to, node, group=False):
        msgid = self._msgid()

        message = Node("message", type="chat", id=msgid)
        message["to"] = to + "@" + (self.GROUPHOST if group else self.SERVER)

        x = Node("x", xmlns="jabber:x:event")
        x.add(Node("server"))

        message.add(x)
        message.add(node)

        return msgid, message
Пример #15
0
    def send_server_properties(self):
        msgid = self._msgid("getproperties")
        node = Node("iq", id=msgid, type="get", xmlns="w", to=self.SERVER)
        node.add(Node("props"))

        self._write(node)
Пример #16
0
    def send_server_properties(self):
        msgid = self._msgid("getproperties")
        node = Node("iq", id=msgid, type="get", xmlns="w", to=self.SERVER)
        node.add(Node("props"))

        self._write(node)