mirror of
https://github.com/Sneed-Group/pypush-plus-plus
synced 2024-12-24 03:42:43 -06:00
remove cruft, organize imports
This commit is contained in:
parent
ba1537ed58
commit
c0f58c2fe2
1 changed files with 59 additions and 120 deletions
151
demo.py
151
demo.py
|
@ -1,12 +1,21 @@
|
||||||
|
import gzip
|
||||||
import json
|
import json
|
||||||
from base64 import b64encode
|
import logging
|
||||||
|
import plistlib
|
||||||
|
import threading
|
||||||
|
import time
|
||||||
|
from base64 import b64decode, b64encode
|
||||||
from getpass import getpass
|
from getpass import getpass
|
||||||
from base64 import b64decode
|
|
||||||
|
from cryptography.hazmat.primitives import hashes, serialization
|
||||||
|
from cryptography.hazmat.primitives.asymmetric import padding, rsa
|
||||||
|
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
|
||||||
|
from cryptography.hazmat.primitives.serialization import load_pem_private_key
|
||||||
|
from rich.logging import RichHandler
|
||||||
|
|
||||||
import apns
|
import apns
|
||||||
import ids
|
import ids
|
||||||
|
from ids.keydec import IdentityKeys
|
||||||
import logging
|
|
||||||
from rich.logging import RichHandler
|
|
||||||
|
|
||||||
FORMAT = "%(message)s"
|
FORMAT = "%(message)s"
|
||||||
logging.basicConfig(
|
logging.basicConfig(
|
||||||
|
@ -22,64 +31,29 @@ logging.getLogger("albert").setLevel(logging.INFO)
|
||||||
logging.getLogger("ids").setLevel(logging.DEBUG)
|
logging.getLogger("ids").setLevel(logging.DEBUG)
|
||||||
logging.getLogger("bags").setLevel(logging.DEBUG)
|
logging.getLogger("bags").setLevel(logging.DEBUG)
|
||||||
|
|
||||||
def input_multiline(prompt):
|
|
||||||
print(prompt)
|
|
||||||
lines = []
|
|
||||||
while True:
|
|
||||||
line = input()
|
|
||||||
if line == "":
|
|
||||||
break
|
|
||||||
lines.append(line)
|
|
||||||
return "\n".join(lines)
|
|
||||||
|
|
||||||
|
|
||||||
# Try and load config.json
|
# Try and load config.json
|
||||||
try:
|
try:
|
||||||
with open("config.json", "r") as f:
|
with open("config.json", "r") as f:
|
||||||
|
|
||||||
CONFIG = json.load(f)
|
CONFIG = json.load(f)
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
CONFIG = {}
|
CONFIG = {}
|
||||||
|
|
||||||
def convert_config(old):
|
|
||||||
new = {}
|
|
||||||
new["id"] = {
|
|
||||||
"key": old["key"],
|
|
||||||
"cert": old["ids_cert"],
|
|
||||||
}
|
|
||||||
new["auth"] = {
|
|
||||||
"key": old["key"],
|
|
||||||
"cert": old["auth_cert"],
|
|
||||||
"user_id": old["user_id"],
|
|
||||||
"handles": [
|
|
||||||
"mailto:user_test2@icloud.com",
|
|
||||||
]
|
|
||||||
#"handles": old["handles"],
|
|
||||||
}
|
|
||||||
new["push"] = {
|
|
||||||
"token": old["push"]["token"],
|
|
||||||
"key": old["push"]["key"],
|
|
||||||
"cert": old["push"]["cert"],
|
|
||||||
}
|
|
||||||
return new
|
|
||||||
|
|
||||||
# Uncomment this to change from an old config.json to a new one
|
|
||||||
#CONFIG = convert_config(CONFIG)
|
|
||||||
|
|
||||||
|
|
||||||
conn = apns.APNSConnection(
|
conn = apns.APNSConnection(
|
||||||
CONFIG.get("push", {}).get("key"), CONFIG.get("push", {}).get("cert")
|
CONFIG.get("push", {}).get("key"), CONFIG.get("push", {}).get("cert")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def safe_b64decode(s):
|
def safe_b64decode(s):
|
||||||
try:
|
try:
|
||||||
return b64decode(s)
|
return b64decode(s)
|
||||||
except:
|
except:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
conn.connect(token=safe_b64decode(CONFIG.get("push", {}).get("token")))
|
conn.connect(token=safe_b64decode(CONFIG.get("push", {}).get("token")))
|
||||||
conn.set_state(1)
|
conn.set_state(1)
|
||||||
conn.filter(["com.apple.madrid"])
|
conn.filter(["com.apple.madrid"])
|
||||||
#print(b64encode(conn.token).decode())
|
|
||||||
user = ids.IDSUser(conn)
|
user = ids.IDSUser(conn)
|
||||||
|
|
||||||
if CONFIG.get("auth", {}).get("cert") is not None:
|
if CONFIG.get("auth", {}).get("cert") is not None:
|
||||||
|
@ -94,9 +68,6 @@ else:
|
||||||
user.authenticate(username, password)
|
user.authenticate(username, password)
|
||||||
|
|
||||||
# Generate a new RSA keypair for the identity
|
# Generate a new RSA keypair for the identity
|
||||||
from cryptography.hazmat.primitives.asymmetric import rsa
|
|
||||||
from cryptography.hazmat.primitives import serialization
|
|
||||||
from cryptography.hazmat.primitives.serialization import load_pem_private_key
|
|
||||||
# Load the old keypair if it exists
|
# Load the old keypair if it exists
|
||||||
if CONFIG.get("encrypt") is not None:
|
if CONFIG.get("encrypt") is not None:
|
||||||
priv_enc = load_pem_private_key(CONFIG["encrypt"].encode(), password=None)
|
priv_enc = load_pem_private_key(CONFIG["encrypt"].encode(), password=None)
|
||||||
|
@ -110,66 +81,25 @@ if CONFIG.get("id", {}).get("cert") is not None:
|
||||||
else:
|
else:
|
||||||
# vd = input_multiline("Enter validation data: ")
|
# vd = input_multiline("Enter validation data: ")
|
||||||
import emulated.nac
|
import emulated.nac
|
||||||
|
|
||||||
vd = emulated.nac.generate_validation_data()
|
vd = emulated.nac.generate_validation_data()
|
||||||
vd = b64encode(vd).decode()
|
vd = b64encode(vd).decode()
|
||||||
|
|
||||||
from ids.keydec import IdentityKeys
|
|
||||||
|
|
||||||
published_keys = IdentityKeys(None, pub_enc)
|
published_keys = IdentityKeys(None, pub_enc)
|
||||||
user.register(vd, published_keys)
|
user.register(vd, published_keys)
|
||||||
|
|
||||||
#logging.info(f"Looked up textgpt@icloud.com, got response: {user.lookup(['mailto:textgpt@icloud.com'])}")
|
|
||||||
|
|
||||||
# logging.info("Enter a username to look up, for example: mailto:textgpt@icloud.com")
|
|
||||||
# while True:
|
|
||||||
# # Read a line from stdin
|
|
||||||
# line = input("> ")
|
|
||||||
# if line == "":
|
|
||||||
# break
|
|
||||||
# # Look up the username
|
|
||||||
# resp = user.lookup([line])
|
|
||||||
# #logging.info(f"Looked up {line}, got response: {user.lookup([line])}")
|
|
||||||
# info = resp[line]
|
|
||||||
# identities = info["identities"]
|
|
||||||
# logging.info(f"Identities: {len(identities)}")
|
|
||||||
# for identity in identities:
|
|
||||||
# logging.info(f"Identity: [yellow]{b64encode(identity['push-token']).decode()}[/] ({len(identity)} properties)", extra={"markup": True})
|
|
||||||
# if len(identity) > 5:
|
|
||||||
# logging.warning(identity)
|
|
||||||
|
|
||||||
#logging.debug(user.lookup(["mailto:usert4@icloud.com", "mailto:jjtech@jjtech.dev"]))
|
|
||||||
# resp = user.lookup(["mailto:jjtech@jjtech.dev"])
|
|
||||||
# info = resp["mailto:jjtech@jjtech.dev"]
|
|
||||||
# identities = info["identities"]
|
|
||||||
# for identity in identities:
|
|
||||||
# logging.info(f"Identity: [yellow]{b64encode(identity['push-token']).decode()}[/] ({len(identity)} properties)", extra={"markup": True})
|
|
||||||
# if "client-data" in identity:
|
|
||||||
# logging.warning(identity["client-data"])
|
|
||||||
logging.info("Waiting for incomming messages...")
|
logging.info("Waiting for incomming messages...")
|
||||||
|
|
||||||
# Create a thread to send keepalive messages
|
# Create a thread to send keepalive messages
|
||||||
import threading
|
|
||||||
import time
|
|
||||||
def keepalive():
|
def keepalive():
|
||||||
while True:
|
while True:
|
||||||
time.sleep(5)
|
time.sleep(5)
|
||||||
conn.keep_alive()
|
conn.keep_alive()
|
||||||
threading.Thread(target=keepalive, daemon=True).start()
|
|
||||||
|
|
||||||
# while True:
|
|
||||||
# # # Wait for a message
|
threading.Thread(target=keepalive, daemon=True).start()
|
||||||
# # # def check_response(x):
|
|
||||||
# # # if x[0] != 0x0A:
|
|
||||||
# # # return False
|
|
||||||
# # # resp_body = apns._get_field(x[1], 3)
|
|
||||||
# # # if resp_body is None:
|
|
||||||
# # # return False
|
|
||||||
# # # resp_body = apns._get_field(x[1], 3)
|
|
||||||
# # # if resp_body is None:
|
|
||||||
# # # return False
|
|
||||||
# # # resp_body = plistlib.loads(resp_body)
|
|
||||||
# # # return resp_body.get('U') == msg_id
|
|
||||||
# pass
|
|
||||||
|
|
||||||
# Write config.json
|
# Write config.json
|
||||||
CONFIG["id"] = {
|
CONFIG["id"] = {
|
||||||
|
@ -187,29 +117,39 @@ CONFIG["push"] = {
|
||||||
"key": user.push_connection.private_key,
|
"key": user.push_connection.private_key,
|
||||||
"cert": user.push_connection.cert,
|
"cert": user.push_connection.cert,
|
||||||
}
|
}
|
||||||
from cryptography.hazmat.primitives import serialization
|
|
||||||
CONFIG["encrypt"] = priv_enc.private_bytes(encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.TraditionalOpenSSL, encryption_algorithm=serialization.NoEncryption()).decode("utf-8").strip()
|
|
||||||
|
CONFIG["encrypt"] = (
|
||||||
|
priv_enc.private_bytes(
|
||||||
|
encoding=serialization.Encoding.PEM,
|
||||||
|
format=serialization.PrivateFormat.TraditionalOpenSSL,
|
||||||
|
encryption_algorithm=serialization.NoEncryption(),
|
||||||
|
)
|
||||||
|
.decode("utf-8")
|
||||||
|
.strip()
|
||||||
|
)
|
||||||
|
|
||||||
with open("config.json", "w") as f:
|
with open("config.json", "w") as f:
|
||||||
json.dump(CONFIG, f, indent=4)
|
json.dump(CONFIG, f, indent=4)
|
||||||
|
|
||||||
|
|
||||||
def decrypt(payload):
|
def decrypt(payload):
|
||||||
import gzip
|
|
||||||
# print(payload[1:3])
|
# print(payload[1:3])
|
||||||
length = int.from_bytes(payload[1:3], "big")
|
length = int.from_bytes(payload[1:3], "big")
|
||||||
# print("Length", length)
|
# print("Length", length)
|
||||||
payload = payload[3 : length + 3]
|
payload = payload[3 : length + 3]
|
||||||
# print("Decrypting payload", payload)
|
# print("Decrypting payload", payload)
|
||||||
from cryptography.hazmat.primitives.asymmetric import padding
|
|
||||||
from cryptography.hazmat.primitives import hashes
|
decrypted1 = priv_enc.decrypt(
|
||||||
decrypted1 = priv_enc.decrypt(payload[:160], padding.OAEP(
|
payload[:160],
|
||||||
|
padding.OAEP(
|
||||||
mgf=padding.MGF1(algorithm=hashes.SHA1()),
|
mgf=padding.MGF1(algorithm=hashes.SHA1()),
|
||||||
algorithm=hashes.SHA1(),
|
algorithm=hashes.SHA1(),
|
||||||
label=None
|
label=None,
|
||||||
))
|
),
|
||||||
|
)
|
||||||
|
|
||||||
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
|
cipher = Cipher(algorithms.AES(decrypted1[:16]), modes.CTR(b"\x00" * 15 + b"\x01"))
|
||||||
cipher = Cipher(algorithms.AES(decrypted1[:16]), modes.CTR(b'\x00'*15 + b'\x01'))
|
|
||||||
decryptor = cipher.decryptor()
|
decryptor = cipher.decryptor()
|
||||||
pt = decryptor.update(decrypted1[16:] + payload[160:])
|
pt = decryptor.update(decrypted1[16:] + payload[160:])
|
||||||
# print(pt)
|
# print(pt)
|
||||||
|
@ -219,8 +159,8 @@ def decrypt(payload):
|
||||||
return payload
|
return payload
|
||||||
|
|
||||||
|
|
||||||
import plistlib
|
|
||||||
while True:
|
while True:
|
||||||
|
|
||||||
def check_response(x):
|
def check_response(x):
|
||||||
if x[0] != 0x0A:
|
if x[0] != 0x0A:
|
||||||
return False
|
return False
|
||||||
|
@ -231,6 +171,7 @@ while True:
|
||||||
if "P" not in resp_body:
|
if "P" not in resp_body:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
payload = conn.incoming_queue.wait_pop_find(check_response)
|
payload = conn.incoming_queue.wait_pop_find(check_response)
|
||||||
resp_body = apns._get_field(payload[1], 3)
|
resp_body = apns._get_field(payload[1], 3)
|
||||||
id = apns._get_field(payload[1], 4)
|
id = apns._get_field(payload[1], 4)
|
||||||
|
@ -240,5 +181,3 @@ while True:
|
||||||
payload = resp_body["P"]
|
payload = resp_body["P"]
|
||||||
payload = decrypt(payload)
|
payload = decrypt(payload)
|
||||||
logging.info(f"Got message: {payload['t']} from {payload['p'][1]}")
|
logging.info(f"Got message: {payload['t']} from {payload['p'][1]}")
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue