From bc02cebc8677c511c7cca956a6207090277f0416 Mon Sep 17 00:00:00 2001 From: JJTech0130 Date: Fri, 7 Apr 2023 22:32:00 -0400 Subject: [PATCH] eyyy it works? --- apns.py | 235 ++++++++++++++++++++++++----------------------------- courier.py | 2 +- demo.py | 35 ++++---- 3 files changed, 126 insertions(+), 146 deletions(-) diff --git a/apns.py b/apns.py index 6823046..cf104d2 100644 --- a/apns.py +++ b/apns.py @@ -2,6 +2,110 @@ from __future__ import annotations import courier, albert from hashlib import sha1 +import threading +import time +import random + +class APNSConnection: + incoming_queue = [] + + def _queue_filler(self): + while True and not self.sock.closed: + #print(self.sock.closed) + #print("QUEUE: Waiting for payload...") + #self.sock.read(1) + print("QUEUE: Got payload?") + payload = _deserialize_payload(self.sock) + #print("QUEUE: Got payload?") + + if payload is not None: + print("QUEUE: Received payload: " + str(payload)) + self.incoming_queue.append(payload) + print("QUEUE: Thread ended") + + def _pop_by_id(self, id: int) -> tuple[int, list[tuple[int, bytes]]] | None: + print("QUEUE: Looking for id " + str(id) + " in " + str(self.incoming_queue)) + for i in range(len(self.incoming_queue)): + if self.incoming_queue[i][0] == id: + return self.incoming_queue.pop(i) + return None + + def wait_for_packet(self, id: int) -> tuple[int, list[tuple[int, bytes]]]: + payload = self._pop_by_id(id) + while payload is None: + payload = self._pop_by_id(id) + time.sleep(0.1) + return payload + + def __init__(self, private_key=None, cert=None): + # Generate the private key and certificate if they're not provided + if private_key is None or cert is None: + self.private_key, self.cert = albert.generate_push_cert() + else: + self.private_key, self.cert = private_key, cert + + self.sock = courier.connect(self.private_key, self.cert) + + # Start the queue filler thread + self.queue_filler_thread = threading.Thread(target=self._queue_filler, daemon=True) + self.queue_filler_thread.start() + + def connect(self, root: bool = True, token: bytes = None): + flags = 0b01000001 + if root: + flags |= 0b0100 + + if token is None: + payload = _serialize_payload(7, [(2, 0x01.to_bytes()), (5, flags.to_bytes(4))]) + else: + payload = _serialize_payload(7, [(1, token), (2, 0x01.to_bytes()), (5, flags.to_bytes(4))]) + + self.sock.write(payload) + + payload = self.wait_for_packet(8) + + if payload == None or payload[0] != 8 or _get_field(payload[1], 1) != 0x00.to_bytes(): + raise Exception("Failed to connect") + + self.token = _get_field(payload[1], 3) + + return self.token + + def filter(self, topics: list[str]): + fields = [(1, self.token)] + + for topic in topics: + fields.append((2, sha1(topic.encode()).digest())) + + payload = _serialize_payload(9, fields) + + self.sock.write(payload) + + def send_message(self, topic: str, payload: str): + payload = _serialize_payload(0x0a, + [(4, random.randbytes(4)), + (1, sha1(topic.encode()).digest()), + (2, self.token), + (3, payload)]) + #print(payload) + + self.sock.write(payload) + + payload = self.wait_for_packet(0x0b) + + #payload = _deserialize_payload(self.sock) + + print(payload) + + def set_state(self, state: int): + self.sock.write(_serialize_payload(0x14, [(1, state.to_bytes(1)), (2, 0x7FFFFFFF.to_bytes(4))])) + + def keep_alive(self): + self.sock.write(_serialize_payload(0x0c, [])) + + # TODO: Find a way to make this non-blocking + #def expect_message(self) -> tuple[int, list[tuple[int, bytes]]] | None: + # return _deserialize_payload(self.sock) def _serialize_field(id: int, value: bytes) -> bytes: @@ -73,133 +177,4 @@ def _get_field(fields: list[tuple[int, bytes]], id: int) -> bytes: for field_id, value in fields: if field_id == id: return value - return None - -import threading,time - -class APNSConnection: - incoming_queue = [] - - def _queue_filler(self): - while True and not self.sock.closed: - #print(self.sock.closed) - #print("QUEUE: Waiting for payload...") - #self.sock.read(1) - print("QUEUE: Got payload?") - payload = _deserialize_payload(self.sock) - #print("QUEUE: Got payload?") - - if payload is not None: - print("QUEUE: Received payload: " + str(payload)) - self.incoming_queue.append(payload) - print("QUEUE: Thread ended") - - def _pop_by_id(self, id: int) -> tuple[int, list[tuple[int, bytes]]] | None: - print("QUEUE: Looking for id " + str(id) + " in " + str(self.incoming_queue)) - for i in range(len(self.incoming_queue)): - if self.incoming_queue[i][0] == id: - return self.incoming_queue.pop(i) - return None - - def __init__(self, private_key=None, cert=None): - # Generate the private key and certificate if they're not provided - if private_key is None or cert is None: - self.private_key, self.cert = albert.generate_push_cert() - else: - self.private_key, self.cert = private_key, cert - - self.sock = courier.connect(self.private_key, self.cert) - - # Start the queue filler thread - self.queue_filler_thread = threading.Thread(target=self._queue_filler) - self.queue_filler_thread.start() - - def connect(self, root: bool = True, token: bytes = None): - flags = 0b01000001 - if root: - flags |= 0b0100 - - if token is None: - payload = _serialize_payload(7, [(2, 0x01.to_bytes()), (5, flags.to_bytes(4))]) - else: - payload = _serialize_payload(7, [(1, token), (2, 0x01.to_bytes()), (5, flags.to_bytes(4))]) - - self.sock.write(payload) - - payload = self._pop_by_id(8) - while payload is None: - payload = self._pop_by_id(8) - print(f"Found {payload}") - time.sleep(0.5) - - if payload == None or payload[0] != 8 or _get_field(payload[1], 1) != 0x00.to_bytes(): - raise Exception("Failed to connect") - - self.token = _get_field(payload[1], 3) - - return self.token - - def filter(self, topics: list[str]): - fields = [(1, self.token)] - - for topic in topics: - fields.append((2, sha1(topic.encode()).digest())) - - payload = _serialize_payload(9, fields) - - self.sock.write(payload) - """Field ID: 4 -Field Value: b'A\xb9\xb9\xd6' -Field ID: 1 -Field Value: b"\xe4\xe6\xd9R\x95Ah\xd0\xa5\xdb\x02\xdb\xaf'\xcc5\xfc\x18\xd1Y" -Field ID: 2 -Field Value: b"\xe5^\xc0c\xe8\xa4\x1e\xbe\x03\x89'\xea\xd5m\x94\x05\xae\xf5\x1bqK\x1aJTH\xa4\xeb8\xb8<\xd7)" -Field ID: 3 -Field Value: b'bplist00\xda\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x0c\x126RsPSfcnQcQERuaQvQiScdvSdtlQU_\x10\x10tel:+16106632676\x10\x01\x10dWpair-ec_\x10#[macOS,13.2.1,22D68,MacBookPro18,3]\x10\x08\x12A\xb9\xb9\xd6\xa5\x13\x1e$*0\xd5\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1dRtPQDRsTQPQt_\x10\x10tel:+16106632676\x08O\x10$\x06\x01E\xf20\x9e\xe9\xa0\x9fT\xd9\x1b\xe1t\xfbBD\xd7e\x13|\xdbA\xc2\xf5^\x13\x05\xb5\x18V5\x13T\xa6\x81O\x11\x01e\n\xf4\x01<\x90]$\xff\xa1\xf2\xde\xe1\xaau\xfa\x87\xbc,+C\xddt\x97\xa0\\f\x8e\xec\xf3\x12C\t\x15ShAb{y\xed\xa4\x8c?\xcf\xf5\xbd\x88\xa4\xf7O\xa0\x9d\xad\x12J\\\xe9p4\xa8\x93d\xf9B\xf7\xcc\xde\xdd\xb6\x16`\xdbm\xd5\xe5\xfbiw\x91\x93m\x8f/\xa4\x92*\xf6\xb7\x1b\x8d\x03\x0f6\x1d\xd2J \xe0\xa6xP\xf1\xdd\xf8\x03Ud&\xc6\xb95\x82=\xc6\xd6`\x84J\xb6F\x8c\xa8\x8d\xa2\x1a\xaa\xf6=\xd1d\x99\xa5\xee\x95\xcd\x80[b\xac\xe0\xed-\x80\xb6LK:\x15}\x9a\xa5\xde\xc8b-\xed+l\x10\x8dr\x16\x10U\x8f\\\xde\xec\xb1\xa45\xdb\xf9%\xc1%\x86\xb2\xfbv.\n&\x87R\xcfw\x8b|g{IC\x0b\n4\xed_\xfc\x15tB\x19jp\xc9\xf0\x9b_\xb2\'\x16g\x98&\xe1\x01\xf3\xf6\x89[\x9d\xa3\xab\xb7\xc7\xe7\x85e\x9c\x1f\xabQ\xf5\xa5l\xd42\xd9\x91|\xe8&\'\x8dmD\x12 U\x15\xb8e\x07ISj\x1bf\x1a@\x16\xb4\x98?\x84z\xd3\x85\x94b\x1f\x05#\x96\xb6\xe6\x88\x12\xaa\x99\x1a@\xf5\x98\x7f\x08\xb8\xdd\xfdo\x1b\xcd\x0c\x07\x9f\xa4\xc9\xd7\xa2z\x8a\xd8\x12\xfa\n\xbc\xb0]\xb1\x9a\x01&\xd9\xd0e\xad\xb8\xf9\x1b\x15\x81\xff\xfa\x11T\rT\xa4\xa1Z\xb2#C\xe4\x1c+\x15Zv\x8e\xd8\x07d\xdf\x89\x17\x9a\x06\x07\rlF\xdc!\xb3\x0cO\x10 \x13\xd4\'\x15\x87\xcf\x8dk\xe1\xde\x17\xba^\x9d\xed\xffy\xf8\xa9H\xda\xbc\xf8\x89S\r;\x92\xc3\xcf\x88\xb6\xd5\x14\x15\x16\x17\x18\x1f !"#_\x10\x1amailto:jjgill07@icloud.com\tO\x10$\x06\x01ieR\x01\x88\x1d\xe7\xe4\x141\xbc\x00\xd2\xb7\x89\x86\x8b\xd1t\x87\x99&\rv\xbf}q\x00\xbe\xb0Q\xee\xf4\x05O\x11\x01e\n\xf4\x01\xcf\x85\xceZ@\xe8\xff\x06\x03)0\x10\x88N\x11\x80B\xa1\x9db\xb2\xe0*\xdc\xb9\t\x93r\x93\x9dj w\xa8#P\xdf}\x95\x0b\x9e\x17\x864\xee\xd0S\xe11c\x9e\xb2\xfewp\x9b\xa7\x83o\x8c\xa14\xd2\x99\x8e\xac\xb9rF\xa1\x8a-\xa9\xe3\x17\xcac(^\x12 \x95\xeaB`\x82\x1d\xf2\xed\x95C\x9d&\x06n\x1dN\xd5[\x9a\x83S\x87\x07\xd7\r\x15\x93\xd5\xa7\xa6\xa0\xddv\xd5\xdb\x9d\xe80\xec}+J\x84uEN\xc6\xd6F\xaf\x0b\x04\x11\xb5\x0b\xe4\x97\x1f]\xbaZ\x96q\xc5\x1bNu\xa8\xd6i\xc8\x8f\xdb\r\xff\xa0\xb7\xc7}Ow\xa1\xd5\x1b\xd3\xb1v\xb6&\xf2\x15\xdb\x10\xbb\xde\x87.W\xa4\xe5\x99\xeap\xf0A\x03\xd2\xdbY5\x01\rIf\xa7]\x00\xd0Kn\xff\x81\xc5\x0b\xb8\x17\xda\x00\xe3\xcf\x11\xdb\x7f\xb9\x16\xc1\x92\x08\xab\xc4\x955\xcb\xeb1&\x0b\xce\x07\xfa\xdb\xa0a\xe2M=q\xd9\xd1\xe1}\xb7\xac\x12 v\x89\xb5\xad\xf2=\x9a\x98\x82\x83\xb4U\x00\xe6\xb7\x11\xd0\xd5G"\xf7G#\x1c \x10\xfc\xe9\x13\xc1\x96c\x1a@\x01u\xc1\xbc\xdaL\xa5\x8a\xca\xee\xfc\x8a\xa6\xa1W\x85\x8aD{+\x16\xd5\xd0\x89\xf8\x07\xba\xfcWJ\xb3*\xd0\x9d\x94\x06:\x8cj[\xf2\xd7\xb6\xdf\xb0z\x17\xad\xe5R\x13S\xa9\xbc\xc0\x89}\x12\x03\xd9\xd1\xed\xdd\xce\x9a\x06\x07\rlF\xdc!\xb3\x0cO\x10 \x13\xd4\'\x15\x87\xcf\x8dk\xe1\xde\x17\xba^\x9d\xed\xffy\xf8\xa9H\xda\xbc\xf8\x89S\r;\x92\xc3\xcf\x88\xb6\xd5\x14\x15\x16\x17\x18% \'()_\x10\x1amailto:jjgill07@icloud.com\tO\x10$\x06\x01\xc0\xaf\xc0\x90\xa5{\xf2\x15\xa8\xb8\x8e\xf0\xf5\xbfL\x15\xc1\xef\x1cJ<\xa5<\x97\xdd\xa1\x0eU6j%Z\x99\xd0O\x11\x01e\n\xf4\x01\xfb\x80\xd1\xca\xc7l\xb58\xd3\x01\xb1\xaa\xcc\xc4\xc0\xaet\xb3:\xee\x14R32\x18\xe0\xfd^\xf1\x8b\xe3\x01\x18\x95\x17\xb6\x7f\x10=\xe5Dl\xb5\xdd*m\xd8\xf5"\x90\x89h+Bc\xad^\x13>\xaa\xcd\xc3p(\xfa\xb6\x03\x93\xad\x1e\x19\xcfkO\x16\xfce`\x95\x90\xa9\xb3\xbe\xf2/\xeeX\x03\x8d\xd5\xa2|\xed\xd9z>d|\xe2l*\xf1\xfaPU\xda\xc5\xb6\x9b=\x90i\xca\t\x9b\xd0K\xfe2^\x9e4o\xb0\xb8c\x86R\xe4Q+\x1e\xf5\xe2\x9eh\xa5\x9b\x8b}\xe9\xd2Zi\x1fS\xe1f \x1a\xe2rA\x842\xae\x06\xa4e\xc57\xd9E\x1a\x03\x02\x7fLP%\xec\xec\x07 \x97\xaf\x0cC&\xfa\x14*\xf4\x0e\xc9\xa26\x01\xfc\xdb\xcdu\x8c\x8d\x8b\xc0Y\xb4 T\xc5\x98Ps}\x8fp\xb4\x03\x0b\xe2&\xd5\x13\xd7\xdd\xd1F_-\x85\xe7\xa8f8 \xec*\x15^F\xbe\x95}\xa2\xac\x8cUr\t\xe4\x98\x0b\x04\x12 \xc9`e\r\xcd\xc8\xd5\xf3\xe9O\x88\xfd[t\x89\xd6\xbbS\xc2I\xdf\xfc\xe3\\\xcfC\x8a%q\x10\xe3T\x1a@\x8a\xeb\r\xd8\xcal\x19\xd2C\x14\x9b\xdc_\x82T\xe4\xf7fVc\xd9\xf39\xa9\xff\x9b\xc9\xb9\xf8%\xf9\xbb\x81\xda\xabE\x8di\xf5\xa2\xbd\x8fJ\xb9\xda\xfc\x11Jn\\\xab_[\xec6\\\x8btF\x14R\x0bX\x98\x9a\x06\x07\rl\rl\xad\xbd\x0cO\x10 \x9c\x1e\x96b\xa5\x15`\xec@C\t\x12\xb4,\xfam\x88\xaeTJ\xae\xb8\xb0\xa6Ypf\xab\xb9\xf3\xe2\x84\xd5\x14\x15\x16\x17\x18+\x1a-./_\x10\x10tel:+16106632676\x08O\x10$\x06\x01\xed\xcf\x17\x93\x05L\xd1\x9c\x89\xa0Cl\xdb-\x15O\x93\x8c\x05\xc1\xc2\xe4\x10\x86\xaf\x0422E\x96\xf1\xb6\xcc\xb7O\x11\x01e\n\xf4\x01]\xa96\xed;\xa3(v\xc2\x9e\xf4\x97\xfe_\xdds\xb7\x99y\xe7\xf0\xea\xf0\xc4\xb1\xdc\x9e\xb9u\x8cD\x1d\xcb\x8d\xe3:^\x0e!\xc3\xb9\xb4\x16Hz^k\x0e\xbc0\xec\xd7"\xba\x8e\x1ax\xe1$\xcf\xa3\x00U\x05\x11\xfe\x86]\xe8\x06/\xb7\xee\x0e\xe6(\xfc\xbd\x1fh6\xa5B\xe3\x14\xfb\x1b\xa8,\xb7\xe1\xe9\xd6gX\xfc\xd9+\xfc\x1d\xea\xc9\x05f}\x1a\xdbTa\x10^\xbb\xde\x1a\xe46O\x7f]x{u\xe2\x8b\x98\x01\xf1\xd0\x12x\xa2Vite;\xad1^\r\xf1\x12\x12\x9a\x96@\x11>\xe0\xabx\x99\xf0\x7f\xdcM\x12\x81g+\xf1\x87\xcbh\x9a\xf7;/\xbc\xe3b\xb5\x07\xa8\xef\xe6F\x16\xb3\xec\xdcnBnp\xbb\x07\xd1 \xee\x97\xd8\xbc\x86\x8e)\x82d0\xec\x94\xe9*i\xce\xf3Fy9\x00[\xea/g\xeb\xaa\xf2\xf3\x89\x8a\x07.DN\x99/\x98\xa5\xe5.\xb2\xb7\x95v\x1f-|\xe7\xbe`t+\xb4\xd2\x12 3r\x9aC\xab\xb4\xcb\x1e|\xaaFz?F\xc5*9\x9d\x95\xe3*\x7f|j]\x17\xad\x02\xe6H\'^\x1a@W\xff\xb7\xf5\xdcb\xba[\x06\n\xd7\x08eq\xfd,\xfd\xf6\xf8$\x9dq.\xf6\xf9wR\x85\xe2\rD\x17F\x01\xd0\x96\xad\xc2\xac\xdb\xde\xd18\xe3ed\xd2\xa13\xb2@\xba\x06\xcf\xe9q\xea\xc5M\x14[\xb7(\x9d\x9a\x06\x07\rl\rl\xad\xbd\x0cO\x10 \x9c\x1e\x96b\xa5\x15`\xec@C\t\x12\xb4,\xfam\x88\xaeTJ\xae\xb8\xb0\xa6Ypf\xab\xb9\xf3\xe2\x84\xd5\x14\x15\x16\x17\x181 345_\x10\x1amailto:jjgill07@icloud.com\tO\x10$\x06\x01\x97\xebO\x04\xc3\xfc\x96\xd0N$\x06\xd6\x12\xaal\x07|\xd1\x17P\xcc\xffI\xead\x03\xb7\xa6N\x9d\xc8\xa3\x7fNO\x11\x01e\n\xf4\x010\xab\xf5[~?\xa8 *=8=(pI\xd4\xc5\xb9\x16`\x83uN\xfeL\x99:^\xb6\xc7\xcc"\x14\xef\x84K;\x9d\xd2\xe0\xa9\x95\x93\xac\x88x3\xfa^\xfb\xb3\x93\xe0P!\xa4\xbeJ\xa7\xc5%\xc07\x13\xb6\xe5\xed5\xc4\x90\xa6\xa0\xfb\xef\x1f9!\x04$\xbai\x99\x95\x1e\x85\x00\xdf`\xa4{\xcd\x0e\x97\xd5\x1e9\xdfgZ\x07\xc6k:\xe8\xee\xbb\x12\x13j\xe8G\xa7C\xcb\nB\xe1\x85\xb0]hY\x8f\x00e\\\x89\xee\x9b2\xf7\xb5\x18\x03\x14\xc5\xb2\xde\xc8h\xc4\x08\x8d(b\xc1\x0bN\xf1\xb6\xd1S\x81\x9f\xbe\x97\xaeZOX\x81ov\xfbX\x9f\xce\xa4N\xe0\xba\xe9\xad\x8e_h\xd7h\x00\x08\x00\x1d\x00 \x00$\x00&\x00(\x00+\x00-\x00/\x003\x007\x009\x00L\x00N\x00P\x00X\x00~\x00\x80\x00\x85\x00\x8b\x00\x96\x00\x99\x00\x9b\x00\x9e\x00\xa0\x00\xa2\x00\xb5\x00\xb6\x00\xdd\x02F\x02i\x02t\x02\x91\x02\x92\x02\xb9\x04"\x04E\x04P\x04m\x04n\x04\x95\x05\xfe\x06!\x06,\x06?\x06@\x06g\x07\xd0\x07\xf3\x07\xfe\x08\x1b\x08\x1c\x08C\t\xac\t\xcf\x00\x00\x00\x00\x00\x00\x02\x01\x00\x00\x00\x00\x00\x00\x007\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\xe2'""" - """ - Field ID: 4 -Field Value: b'A\xb9\xb9\xd6' -Field ID: 1 -Field Value: b"\xe4\xe6\xd9R\x95Ah\xd0\xa5\xdb\x02\xdb\xaf'\xcc5\xfc\x18\xd1Y" -Field ID: 2 -Field Value: b"\xe5^\xc0c\xe8\xa4\x1e\xbe\x03\x89'\xea\xd5m\x94\x05\xae\xf5\x1bqK\x1aJTH\xa4\xeb8\xb8<\xd7)" -Field ID: 3 -Field Value: b'bplist00\xdd\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x13\x17\x18\x19ScdrRtPRgdQiRsPRnrQcQUQtScdvRuaRqHQvM\x08\xd6\xf3\xe6\x8d\x04\x18\x95\xfd\xea\xe9\xf50_\x10\x10tel:+16106632676\t\x12=\x12c&_\x10\x1amailto:jjgill07@icloud.com\x10\x01\x10mO\x10\x10UC>\x9f\xce\xa4N\xe0\xba\xe9\xad\x8e_h\xd7hO\x10 \xe5^\xc0c\xe8\xa4\x1e\xbe\x03\x89\'\xea\xd5m\x94\x05\xae\xf5\x1bqK\x1aJTH\xa4\xeb8\xb8<\xd7)_\x10#[macOS,13.2.1,22D68,MacBookPro18,3]O\x10!\x01\x97\xca\\"\xcaI\x82\x0c\xb66C\xa7\x89h\x91\xcd\x18Ozj"\x06u;9\x96\xebrQs|=\x10\x08\x00\x08\x00#\x00\'\x00*\x00-\x00/\x002\x005\x007\x009\x00;\x00?\x00B\x00E\x00G\x00U\x00h\x00i\x00n\x00\x8b\x00\x8d\x00\x8f\x00\xa2\x00\xc5\x00\xeb\x01\x0f\x00\x00\x00\x00\x00\x00\x02\x01\x00\x00\x00\x00\x00\x00\x00\x1a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x11'""" - def send_message(self, token: bytes, topic: str, payload: str): - # Current time in UNIX nanoseconds - import time - # Expire in 5 minutes - expiry = int(time.time()) + 500 - #print(sha1(topic.encode()).digest()) - payload = _serialize_payload(0x0a, - [(4, b'A\xb9\xb9\xd7'), - (1, sha1(topic.encode()).digest()), - (2, token), - (3, payload),]) - # payload = _serialize_payload(0x0a, - # [(1, sha1(topic.encode()).digest()), - # (2, token), - # (3, payload.encode("utf-8")), - # (4, (3864024149).to_bytes(4, "big")), - # (5, expiry.to_bytes(4, "big")), - # (6, time.time_ns().to_bytes(8, "big")), - # (7, 0x00.to_bytes()), - # (0xf, self.token)]) - - print(payload) - - self.sock.write(payload) - - payload = _deserialize_payload(self.sock) - - print(payload) - - def set_state(self, state: int): - self.sock.write(_serialize_payload(0x14, [(1, state.to_bytes(1)), (2, 0x7FFFFFFF.to_bytes(4))])) - - def keep_alive(self): - self.sock.write(_serialize_payload(0x0c, [])) - - # TODO: Find a way to make this non-blocking - def expect_message(self) -> tuple[int, list[tuple[int, bytes]]] | None: - return _deserialize_payload(self.sock) \ No newline at end of file + return None \ No newline at end of file diff --git a/courier.py b/courier.py index 2193f30..3288637 100644 --- a/courier.py +++ b/courier.py @@ -1,7 +1,7 @@ import tlslite import socket -COURIER_HOST = "1-courier.push.apple.com" # TODO: Get this from config +COURIER_HOST = "windows.courier.push.apple.com" # TODO: Get this from config COURIER_PORT = 5223 ALPN = [b"apns-security-v2"] diff --git a/demo.py b/demo.py index 7980097..bd251a4 100644 --- a/demo.py +++ b/demo.py @@ -6,25 +6,30 @@ conn1 = apns.APNSConnection() conn1.connect() conn1.keep_alive() conn1.set_state(0x01) -print(f"Push Token 1: {b64encode(conn1.token).decode()}") - -#while True: -# pass conn1.filter([]) conn1.connect(False) -print(f"User Token 1: {b64encode(conn1.token).decode()}") - -# conn2 = apns.APNSConnection() -# conn2.connect() -# conn2.filter([]) -# print(f"Push Token 2: {b64encode(conn2.token).decode()}") -# conn2.connect(False) -# print(f"User Token 2: {b64encode(conn2.token).decode()}") - conn1.filter(["com.apple.madrid"]) -# conn2.filter(["com.apple.madrid"]) +conn1.send_message("com.apple.madrid", b'bplist00\xd9\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x1dRsPSfcnQcQERuaQvQiSdtlQU_\x10\x1amailto:jjgill07@icloud.com\x10\x01\x10\xf2Wpair-ec_\x10#[macOS,13.2.1,22D68,MacBookPro18,3]\x10\x08\x12$\x01\xe0c\xa1\x12\xd5\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1cRtPQDRsTQPQt_\x10\x1amailto:jjgill07@icloud.com\x08O\x10"\x06\x01r\x00b4\x99\xa5\xd9\xfaf\xda\xabUX\x8f\xf3\x98o\xe6 \xfb\xa2\xd4\xeeH{W.\xc6\xbc\xb1\x184O\x11\x019\n\xc8\x01\x9e\xea^S\x9fFy"\x0e\xa8zi\xee\xa9\x11^\xa3\x1ee]\xae{\xf8@~\xb0p\x07\xb8\xf9\xd2+\x15\x7fy\x8a\x1d\x9b]V\x8cG6\x94\xdf4\xa7\x1e\xe7\xddR]\xe2\x9f\xda\xbf\x927RD]\xb9\x04\xc6U\xa6\xfe!D\x9f\xfd\xa1\xac?X\xc0l\x08\nv\x1b\xc2\xbf\xd8a\x1d\xc6\x99G\xaeV\xbd\xaa\x7f\x91*\xc6\xffvC\x9c9>\x93\xe1\x04\xc2\xc3\xcc-\xd6\xac1j\xc5\x1cR\xbf)Zp\xf4\xbd\x04\xaa\xa5\x7f5e\xf9\x1dq%T\xb2\xdf\xa4{\xa8A\x97\x87\\=|s\x87o\x14\xbe\xd6\xd7\x0e\x81\x91G\x9f\xbe\xedRU\x86.\xd0i\xdd\x80\xcep#\xb01Mv\x97\x9e\x89\'\xb4\x08DUYv\xd5\xaa\xb5\xb14\xc9L\x0c\xdf\x04\x85\x1bK\xfd\xc1\xee\x12 n\xb0\xd1\x92\x16\xfd\xb8\x1e\xc3J\xd9*\x11\x84\xea3\xc5s\xed\xd5\xe3\x16\xc8\x90\xb6t\\\x9b\x87\xe4)\xc3\x1a@\x8f\xa0\xeb\x01\x84\xce7#\x86\x92\x82\xaa\xac\t\x07\xcf\x1b\xfa\xeeZb\xdf\x1a#\xd0_\x12#f\xdc\xef{\x9f\xf7\x1b\xb0\xd9\x17\x01\xe6\x8c$\x1d[\xca\xeb\x1fV3\x842Z\xcb\xa8G\xce\x00\xc5\xc2n\x8e\xd8\x8ck\x9a\x06\x07\rlF\xdc!\xb3\x0cO\x10 \x13\xd4\'\x15\x87\xcf\x8dk\xe1\xde\x17\xba^\x9d\xed\xffy\xf8\xa9H\xda\xbc\xf8\x89S\r;\x92\xc3\xcf\x88\xb6O\x10\x10\xe3\x89E\xdd\xcc|B\x11\xac\x86\x95vl\xc2\x01\xa0\x00\x08\x00\x1b\x00\x1e\x00"\x00$\x00&\x00)\x00+\x00-\x001\x003\x00P\x00R\x00T\x00\\\x00\x82\x00\x84\x00\x89\x00\x8b\x00\x96\x00\x99\x00\x9b\x00\x9e\x00\xa0\x00\xa2\x00\xbf\x00\xc0\x00\xe5\x02"\x02E\x00\x00\x00\x00\x00\x00\x02\x01\x00\x00\x00\x00\x00\x00\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02X') -conn1.send_message(b"\xe5^\xc0c\xe8\xa4\x1e\xbe\x03\x89'\xea\xd5m\x94\x05\xae\xf5\x1bqK\x1aJTH\xa4\xeb8\xb8<\xd7)", "com.apple.madrid", b'bplist00\xdd\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x13\x17\x18\x19ScdrRtPRgdQiRsPRnrQcQUQtScdvRuaRqHQvM\x08\xd6\xf3\xe6\x8d\x04\x18\x95\xfd\xea\xe9\xf50_\x10\x10tel:+16106632676\t\x12=\x12c&_\x10\x1amailto:jjgill07@icloud.com\x10\x01\x10mO\x10\x10UC>\x9f\xce\xa4N\xe0\xba\xe9\xad\x8e_h\xd7hO\x10 \xe5^\xc0c\xe8\xa4\x1e\xbe\x03\x89\'\xea\xd5m\x94\x05\xae\xf5\x1bqK\x1aJTH\xa4\xeb8\xb8<\xd7)_\x10#[macOS,13.2.1,22D68,MacBookPro18,3]O\x10!\x01\x97\xca\\"\xcaI\x82\x0c\xb66C\xa7\x89h\x91\xcd\x18Ozj"\x06u;9\x96\xebrQs|=\x10\x08\x00\x08\x00#\x00\'\x00*\x00-\x00/\x002\x005\x007\x009\x00;\x00?\x00B\x00E\x00G\x00U\x00h\x00i\x00n\x00\x8b\x00\x8d\x00\x8f\x00\xa2\x00\xc5\x00\xeb\x01\x0f\x00\x00\x00\x00\x00\x00\x02\x01\x00\x00\x00\x00\x00\x00\x00\x1a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x11') +# #print(f"Push Token 1: {b64encode(conn1.token).decode()}") + +# #while True: +# # pass +# #conn1.filter([]) +# conn1.connect(False) +# print(f"User Token 1: {b64encode(conn1.token).decode()}") + +# # conn2 = apns.APNSConnection() +# # conn2.connect() +# # conn2.filter([]) +# # print(f"Push Token 2: {b64encode(conn2.token).decode()}") +# # conn2.connect(False) +# # print(f"User Token 2: {b64encode(conn2.token).decode()}") + +# conn1.filter(["com.apple.madrid"]) +# # conn2.filter(["com.apple.madrid"]) + +# conn1.send_message(b"\xe5^\xc0c\xe8\xa4\x1e\xbe\x03\x89'\xea\xd5m\x94\x05\xae\xf5\x1bqK\x1aJTH\xa4\xeb8\xb8<\xd7)", "com.apple.madrid", b'bplist00\xdd\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x13\x17\x18\x19ScdrRtPRgdQiRsPRnrQcQUQtScdvRuaRqHQvM\x08\xd6\xf3\xe6\x8d\x04\x18\x95\xfd\xea\xe9\xf50_\x10\x10tel:+16106632676\t\x12=\x12c&_\x10\x1amailto:jjgill07@icloud.com\x10\x01\x10mO\x10\x10UC>\x9f\xce\xa4N\xe0\xba\xe9\xad\x8e_h\xd7hO\x10 \xe5^\xc0c\xe8\xa4\x1e\xbe\x03\x89\'\xea\xd5m\x94\x05\xae\xf5\x1bqK\x1aJTH\xa4\xeb8\xb8<\xd7)_\x10#[macOS,13.2.1,22D68,MacBookPro18,3]O\x10!\x01\x97\xca\\"\xcaI\x82\x0c\xb66C\xa7\x89h\x91\xcd\x18Ozj"\x06u;9\x96\xebrQs|=\x10\x08\x00\x08\x00#\x00\'\x00*\x00-\x00/\x002\x005\x007\x009\x00;\x00?\x00B\x00E\x00G\x00U\x00h\x00i\x00n\x00\x8b\x00\x8d\x00\x8f\x00\xa2\x00\xc5\x00\xeb\x01\x0f\x00\x00\x00\x00\x00\x00\x02\x01\x00\x00\x00\x00\x00\x00\x00\x1a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x11') # while True: