mirror of
https://github.com/Sneed-Group/pypush-plus-plus
synced 2025-01-09 17:33:47 +00:00
incorporate most of June's changes
This commit is contained in:
parent
0fc17b6d83
commit
c9664c1ce1
6 changed files with 139 additions and 20 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -163,3 +163,7 @@ cython_debug/
|
||||||
.idea/
|
.idea/
|
||||||
|
|
||||||
attachments/
|
attachments/
|
||||||
|
|
||||||
|
proxy/hosts.proxy
|
||||||
|
proxy/lldb_commands.txt
|
||||||
|
proxy/imessage_proxy.pac
|
|
@ -1,7 +1,7 @@
|
||||||
import plistlib
|
import plistlib
|
||||||
import re
|
import re
|
||||||
import uuid
|
import uuid
|
||||||
from base64 import b64decode, b64encode
|
from base64 import b64decode
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
from cryptography import x509
|
from cryptography import x509
|
||||||
|
|
3
apns.py
3
apns.py
|
@ -21,7 +21,10 @@ import bags
|
||||||
logger = logging.getLogger("apns")
|
logger = logging.getLogger("apns")
|
||||||
|
|
||||||
# Pick a random courier server from 01 to APNSCourierHostcount
|
# Pick a random courier server from 01 to APNSCourierHostcount
|
||||||
|
try:
|
||||||
COURIER_HOST = f"{random.randint(1, bags.apns_init_bag()['APNSCourierHostcount'])}-{bags.apns_init_bag()['APNSCourierHostname']}"
|
COURIER_HOST = f"{random.randint(1, bags.apns_init_bag()['APNSCourierHostcount'])}-{bags.apns_init_bag()['APNSCourierHostname']}"
|
||||||
|
except:
|
||||||
|
COURIER_HOST = "01-courier.push.apple.com"
|
||||||
COURIER_PORT = 5223
|
COURIER_PORT = 5223
|
||||||
ALPN = [b"apns-security-v3"]
|
ALPN = [b"apns-security-v3"]
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ def parse_key(key: str):
|
||||||
else:
|
else:
|
||||||
return serialization.load_pem_private_key(key.encode(), None)
|
return serialization.load_pem_private_key(key.encode(), None)
|
||||||
|
|
||||||
def serialize_key(key):
|
def serialize_key(key) -> str:
|
||||||
if isinstance(key, ec.EllipticCurvePrivateKey) or isinstance(key, rsa.RSAPrivateKey):
|
if isinstance(key, ec.EllipticCurvePrivateKey) or isinstance(key, rsa.RSAPrivateKey):
|
||||||
return key.private_bytes(
|
return key.private_bytes(
|
||||||
encoding=serialization.Encoding.PEM,
|
encoding=serialization.Encoding.PEM,
|
||||||
|
|
|
@ -1,17 +1,21 @@
|
||||||
|
import os
|
||||||
import sys
|
import sys
|
||||||
sys.path.append("../")
|
|
||||||
sys.path.append("../../")
|
|
||||||
|
|
||||||
import apns
|
# setting path so we can import the needed packages
|
||||||
import trio
|
sys.path.append(os.path.join(sys.path[0], "../"))
|
||||||
import ssl
|
sys.path.append(os.path.join(sys.path[0], "../../"))
|
||||||
|
|
||||||
import logging
|
|
||||||
from rich.logging import RichHandler
|
|
||||||
from hashlib import sha1
|
|
||||||
import plistlib
|
|
||||||
import gzip
|
import gzip
|
||||||
|
import logging
|
||||||
|
import plistlib
|
||||||
|
import ssl
|
||||||
|
from hashlib import sha1
|
||||||
|
|
||||||
|
import trio
|
||||||
|
from rich.logging import RichHandler
|
||||||
|
|
||||||
|
import printer
|
||||||
|
import apns
|
||||||
|
|
||||||
logging.basicConfig(
|
logging.basicConfig(
|
||||||
level=logging.NOTSET,
|
level=logging.NOTSET,
|
||||||
|
@ -26,7 +30,8 @@ async def main():
|
||||||
context = ssl.create_default_context(purpose=ssl.Purpose.CLIENT_AUTH)
|
context = ssl.create_default_context(purpose=ssl.Purpose.CLIENT_AUTH)
|
||||||
context.set_alpn_protocols(["apns-security-v3"])
|
context.set_alpn_protocols(["apns-security-v3"])
|
||||||
# Set the certificate and private key
|
# Set the certificate and private key
|
||||||
context.load_cert_chain("push_certificate_chain.pem", "push_key.pem")
|
parent_dir: str = os.path.dirname(os.path.realpath(__file__))
|
||||||
|
context.load_cert_chain(os.path.join(parent_dir, "push_certificate_chain.pem"), os.path.join(parent_dir, "push_key.pem"))
|
||||||
|
|
||||||
await trio.serve_ssl_over_tcp(handle_proxy, 5223, context)
|
await trio.serve_ssl_over_tcp(handle_proxy, 5223, context)
|
||||||
|
|
||||||
|
@ -43,7 +48,10 @@ class APNSProxy:
|
||||||
self.client = client
|
self.client = client
|
||||||
|
|
||||||
async def start(self):
|
async def start(self):
|
||||||
|
logging.info("Starting proxy...")
|
||||||
async with trio.open_nursery() as nursery:
|
async with trio.open_nursery() as nursery:
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
apns_server = apns.APNSConnection(nursery)
|
apns_server = apns.APNSConnection(nursery)
|
||||||
await apns_server._connect_socket()
|
await apns_server._connect_socket()
|
||||||
self.server = apns_server.sock
|
self.server = apns_server.sock
|
||||||
|
@ -51,6 +59,12 @@ class APNSProxy:
|
||||||
nursery.start_soon(self.proxy, True)
|
nursery.start_soon(self.proxy, True)
|
||||||
nursery.start_soon(self.proxy, False)
|
nursery.start_soon(self.proxy, False)
|
||||||
|
|
||||||
|
break # Will only happen if there is no exception
|
||||||
|
except Exception:
|
||||||
|
logging.error("Unable to start proxy, trying again...")
|
||||||
|
await trio.sleep(1)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async def proxy(self, to_server: bool):
|
async def proxy(self, to_server: bool):
|
||||||
if to_server:
|
if to_server:
|
||||||
|
@ -66,7 +80,6 @@ class APNSProxy:
|
||||||
await payload.write_to_stream(to_stream)
|
await payload.write_to_stream(to_stream)
|
||||||
|
|
||||||
def log(self, payload: apns.APNSPayload, to_server: bool):
|
def log(self, payload: apns.APNSPayload, to_server: bool):
|
||||||
import printer
|
|
||||||
printer.print_payload(payload, to_server)
|
printer.print_payload(payload, to_server)
|
||||||
# if to_server:
|
# if to_server:
|
||||||
# logging.info(f"-> {payload}")
|
# logging.info(f"-> {payload}")
|
||||||
|
|
99
proxy/start_proxy.sh
Executable file
99
proxy/start_proxy.sh
Executable file
|
@ -0,0 +1,99 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
err() {
|
||||||
|
echo -e "\e[31m[!]\e[0m ${1}" 1>&2
|
||||||
|
}
|
||||||
|
|
||||||
|
inf() {
|
||||||
|
echo -e "\e[34m[*]\e[0m ${1}"
|
||||||
|
}
|
||||||
|
|
||||||
|
leave() {
|
||||||
|
[ -f /etc/hosts.bak ] && { inf "Fixing /etc/hosts..." && sudo mv /etc/hosts.bak /etc/hosts; }
|
||||||
|
|
||||||
|
[ -z ${lldb_pid+x} ] || { inf "Killing attached lldb..." && { sudo kill "$lldb_pid" 2>/dev/null || :; }; }
|
||||||
|
[ -z ${mitm_pid+x} ] || { inf "Killing mitmweb..." && { kill "$mitm_pid" 2>/dev/null || :; }; }
|
||||||
|
[ -z ${proxy_pid+x} ] || { inf "Killing proxy..." && { kill "$proxy_pid" 2>/dev/null || :; }; }
|
||||||
|
|
||||||
|
cd "$old_dir" || :
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
[[ "$(uname)" != "Darwin" ]] && { err "This can only be run on macOS" && exit 1; }
|
||||||
|
|
||||||
|
old_dir="$(pwd)"
|
||||||
|
root_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||||
|
full_dir="$root_dir"
|
||||||
|
[[ "$old_dir" == "$root_dir" ]] && root_dir="."
|
||||||
|
|
||||||
|
trap 'leave' INT ERR
|
||||||
|
|
||||||
|
proxy_dir="${root_dir}"
|
||||||
|
|
||||||
|
inf "Setting up \e[1mhosts.proxy\e[0;34m..."
|
||||||
|
|
||||||
|
hosts_proxy="${proxy_dir}/hosts.proxy"
|
||||||
|
cat /etc/hosts > "$hosts_proxy"
|
||||||
|
python3 "${proxy_dir}/hosts.py" >> "$hosts_proxy"
|
||||||
|
|
||||||
|
echo -e "\e[32m[?]\e[0;1m ${hosts_proxy}\e[0m must be copied over to /etc/hosts. Would you like us to do that for you? [y/n]"
|
||||||
|
read -rn1 answer
|
||||||
|
if [[ "${answer,,}" == "y" ]]
|
||||||
|
then
|
||||||
|
inf "Backing up /etc/hosts to /etc/hosts.bak and copying ${hosts_proxy} to /etc/hosts"
|
||||||
|
sudo cp /etc/hosts /etc/hosts.bak
|
||||||
|
sudo cp "$hosts_proxy" /etc/hosts
|
||||||
|
fi
|
||||||
|
|
||||||
|
lldb_commands="${proxy_dir}/lldb_commands.txt"
|
||||||
|
cat << EOF > "$lldb_commands"
|
||||||
|
breakpoint set -n "SecTrustEvaluateWithError" -C "thread return 1" -C "c"
|
||||||
|
c
|
||||||
|
EOF
|
||||||
|
|
||||||
|
inf "Attaching to lldb..."
|
||||||
|
env TERM=xterm-256color sudo lldb -p $(pgrep apsd) -s "$lldb_commands" >/dev/null &
|
||||||
|
lldb_pid=$!
|
||||||
|
|
||||||
|
cat << EOF > "${proxy_dir}/imessage_proxy.pac"
|
||||||
|
// https://en.wikipedia.org/wiki/Proxy_auto-config for reference
|
||||||
|
function FindProxyForURL(url, host) {
|
||||||
|
// to redirect apns tcp traffic
|
||||||
|
if (shExpMatch(host, '*-courier.push.apple.com')) {
|
||||||
|
// this should redirect it to mitmproxy if it's running.
|
||||||
|
// should 127.0.0.1:8080 fail to respond, it should just forward it
|
||||||
|
return 'PROXY 127.0.0.1:8080; DIRECT';
|
||||||
|
}
|
||||||
|
|
||||||
|
// to redirect ids stuff
|
||||||
|
if (shExpMatch(host, '*ess.apple.com')) {
|
||||||
|
return 'PROXY 127.0.0.1:8080; DIRECT';
|
||||||
|
}
|
||||||
|
|
||||||
|
// for everything else, just forward it
|
||||||
|
return 'DIRECT'
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
inf "Setting up proxy auto-config..."
|
||||||
|
networksetup -setautoproxyurl Wi-Fi "file://${full_dir}/imessage_proxy.pac"
|
||||||
|
|
||||||
|
inf "Starting up mitmweb..."
|
||||||
|
mitmweb &
|
||||||
|
mitm_pid=$!
|
||||||
|
|
||||||
|
inf "Running apns proxy..."
|
||||||
|
python3 "${proxy_dir}/proxy.py" &
|
||||||
|
proxy_pid=$!
|
||||||
|
|
||||||
|
# need to give the proxy a second to start up or it yells at us
|
||||||
|
sleep 1
|
||||||
|
|
||||||
|
inf "Restarting wifi to force apsd to reconnect..."
|
||||||
|
networksetup -setairportpower en0 off
|
||||||
|
networksetup -setairportpower en0 on
|
||||||
|
|
||||||
|
while true; do read -rn1 _; done
|
Loading…
Reference in a new issue