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))
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))
def _read(self): length = self.list_start() token = self.peek_int8() if token == 0x01: self._consume(1) attributes = self.attributes(length) return Node("start", **attributes) elif token == 0x02: self._consume(1) raise EndOfStream() node = Node(self.string()) node.attributes = self.attributes(length) if (length % 2) == 0: token = self.peek_int8() if token == 0xf8 or token == 0xf9: node.children = self.list() else: node.data = self.string() return node
def _read(self): length = self.list_start() token = self._peek(1) if token == "\x01": self._consume(1) attributes = self.attributes(length) return Node("start", **attributes) if token == "\x02": self._consume(1) raise EndOfStream() node = Node(self.string()) node.attributes = self.attributes(length) if (length % 2) == 0: token = self._peek(1) if token == "\xF8" or token == "\xF9": node.children = self.list() else: node.data = self.string() return node