Giter VIP home page Giter VIP logo

pypush's Introduction

Warning

pypush is undergoing a major rewrite. The current version is not stable and may not work as expected. Many features have been temporarily removed.

Versioning starts at 2.0.0 due to conflicts with the original package to have the pypush name. Do not expect stability until 3.0.0.

pypush

pypush was originally a POC demo of my recent iMessage reverse-engineering. It is now being developed into a community library aiming to cover all of Apple's internal API surface.

Currently, the rewritten version supports using the client side of Apple's internal APNs API, meaning it can activate as an Apple device and receive push notifications. Stay tuned for future updates as we bring back the iMessage API and more!

pypush is completely platform-independent, though it may require device identifiers to use some APIs.

Installation

Simple installation:

pip install pypush[cli]

Editable installation (for development):

git clone https://github.com/JJTech0130/pypush
cd pypush
pip install -e .

Licensing

This project is licensed under the terms of the SSPL

This project has been purchased by Beeper, please contact them with any questions about licensing.

pypush's People

Contributors

dadoum avatar danipoak avatar eltociear avatar jjtech0130 avatar kasherpete avatar peterkw avatar pixelmonaskarion avatar spacesaver avatar thomashzhang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pypush's Issues

SSPL License Issues

Hi,
I noticed on your GitHub profile you mentioned PyPush was open sourced, however according to the creators of the SSPL license (MongoDB), the SSPL license is not open sourced (source).
Are there any plans to perhaps switch the license in the future?
Thank you for creating this incredible project!

Add the ability to change the 2FA mode

My apple account is connected with my home mac and some other macs (Beeper and other services), I do not have readily access to these mac's and as such using 2FA is a pain. There should in theory be a way to switch the 2FA mode to the phone number associated with the apple account. This is more of a 'nice to have' than actually being necessary, but would still be a good feature none the less.

Consider making a pip package?

This is a great looking library, and I think it would help a whole lot if you made a python package.

Thanks,
Gammer0909

has been no response.

For the last few days, I tried send imessage ,"is me" is my content ,But the continuous absence of a response.. and type help not show message, Any idea what could be the issue or how I could fix this?

[02:06:04] INFO Connected to APNs (5-courier.push.apple.com) apns.py:39
INFO Waiting for incoming messages... demo.py:91
Type 'help' for help

help
help (h): show this message
quit (q): quit
filter (f) [recipient]: set the current chat
effect (e): adds an iMessage effect to the next sent message
note: recipient must start with tel: or mailto: and include the country code
handle : set the current handle (for sending messages)
: escape commands (will be removed from message)
filter +18023061555
Filtering to ['tel:+18023061555']
is me
help

Validation data expired!

This "IOPlatformSerialNumber" replaces multiple device codes with "raise Exception("Validation data expired!"). )
Exception: Validation data expired!”

Cat and Mouse?

With Beeper so heavily in the news, I suspect Apple has derailed the mechanism this project uses to send and receive messages. I compiled and ran nacserver (JJTech0130/nacserver) on a valid Intel Mac and swapped out the data.plist file on my Linux box. I reran the initialization to get a new config.json but the software no longer appears to function correctly. This is too bad since it was nice to be able to ssh in from wherever I was working and send iMessages.

Steps to Replicate

  1. Clone nacserver on an Intel Mac
  2. Run build.sh
  3. Copy data.plist into emulated directory under pypush
  4. rm existing config.json
  5. Run demo.py with requirements.txt installed
  6. No Joy

Fix 2FA stuff

Currently very buggy, doesn’t check if account had no 2FA

Fix `crontab -e` being hidden

crontab -e here is hidden because it's on the same line as ```, so the markdown parser is reading it as the syntax highlight language instead of the codeblock body.

pypush/README.md

Lines 98 to 100 in b81ae39

2. To automatically reregister every 30 minutes, execute the following:
```crontab -e
```

I'd also suggest changing it to

$ crontab -e

(adding $) for clarity that it's a terminal command and not something that goes in a file, but that's up to you (should be clear to anybody who reads the directions anyways). if you do decide to add that, should also be added to the other commands, but not terribly important.

demo stuck in Waiting for incoming messages

[03:04:10] INFO     Connected to APNs (16-courier.push.apple.com)                                                                     apns.py:40
[03:04:11] INFO     Waiting for incoming messages...                                                                                  demo.py:94
Type 'help' for help

I remove the config.json but same issue (still debugging)

Relicense to a free license

Hi,

The "Server Side Public License" is not known to be a license that is actually free/open source -- it's not known that it complies with the Four Freedoms, the Open Source Definition, or the Debian Free Software Guidelines. Although it's possible that the SSPL is actually free and open source, the SSPL's vagueness about how "viral" it is and its extreme copyleft has raised concern amongst open source and free software advocates. Additionally, it's not compatible with the GPL, meaning that pypush can't use any GPL libraries, nor can GPL-licensed projects incorporate pypush. Since pypush is being rewritten, would it be possible to relicense pypush under a well-known license, such as Apache-2.0, LGPL, GPL, or AGPL?

Thanks!

Basic UI needed

If not complex i think a basic UI will be helpful instead of all going through terminal that's what I think

Request queued messages from APNs

On iOS it currently receives missed messages on boot if device was turned off for multiple hours of time and starting up it takes a bit of time but it receives messages that were missed. This would be very useful for locally ran stuff like inside of a app or executable where it might not always be active and someone could message during that time.

install issue

$ python3 -m pip install --editable ./pypush - > $ python3 -m pip install --editable ../pypush

search_party_token always null

after run the bellow code show Logged in! message

~/pypush$ python3 ./examples/openhaystack.py

but show this error:
Error fetching locations (ratelimit?): 401

in the openhaystack.json
"search_party_token": null,

Use of context on `APNSConnection.start` and its limitations

Here is some code I did to be able to use PyPush as a library.

    @classmethod
    async def from_save(
        cls,
        fp: Path
    ) -> "StoredAuthorizedUser":
        with open(fp, "r") as read:
            data = json.load(read)
        
        push_creds = apns.PushCredentials(
            private_key=data["push"]["key"],
            cert=data["push"]["cert"],
            token=base64.b64decode(data["push"]["token"])
        )

        user = data["user"]
        async with apns.APNSConnection.start(push_creds) as connection:
            user = ids.IDSUser( push_connection=connection,
                                user_id=user["id"],
                                auth_keypair=ids._helpers.KeyPair(user["auth_key"], user["auth_cert"]),
                                encryption_identity=ids.identity.IDSIdentity(user["signing_key"], user["encryption_key"]),
                                id_cert=None,
                                handles=user["handles"], )
                
            return cls(
                connection=connection,
                user=user,
                certificates=data.get("certs"),
                earliest_expiration=data.get("earliest_expiration")
            )

You can see at the end of this method that I am trying to put my connection to my __init__ method of my class. However, since the connection is in a context, I can't. When we hit return, even inside of a context, the context gets closed. So I can't use the connection outside of the context. If I do it, it will result in the following error, confirming that the connection got closed:

Capture d’écran 2023-11-25 à 22 42 38

If you try to do some of the following stuff, it won't work, or due of the limitations of trio, or due to the limitations of context manager.

connection = apns.APNSConnection.start(push_creds)
connection = await apns.APNSConnection.start(push_creds)
connection = await apns.APNSConnection.start(push_creds).__anext__()

I've also tried to return just after the yield (in the following code) to return the connection, to avoid closing it, etc ... And it just freezes the code.

pypush/apns.py

Lines 155 to 164 in bacefed

@asynccontextmanager
@staticmethod
async def start(credentials: PushCredentials = PushCredentials()):
"""Sets up a nursery and connection and yields the connection"""
async with trio.open_nursery() as nursery:
connection = APNSConnection(nursery, credentials)
await connection.connect()
yield connection
nursery.cancel_scope.cancel() # Cancel heartbeat and queue filler tasks
await connection.sock.aclose() # Close the socket

What could I do to avoid the automatic closing of my connection / How can I open it with a manual closing ? (All of this using the async version ofc)

Implement receiving app push notifications

I am not an iOS developer myself, but every now and then I have to do some testings, and one of the things it is requested is a real device to test push notifications, I wonder if this approach can be used for that as well?

Thanks!

Termux

Is it possible to do it on Termux on Android? I'm missing dependencies

Edit: Add lines to make it work
Edit: Closing as it works now

git clone -b sms-registration https://github.com/JJTech0130/pypush 
cd pypush
pkg install build-essential
pkg install binutils
#pkg install pkg_resources
pip3 install setuptools
pip3 install trio
pip3 install -r requirements.txt
#change IP address to current
#Check Gateway number, UK is +447786205094 def register(push_token: bytes, gateway = "22223333")
python3 ./demo.py
error occurred: Failed to find tool. Is `aarch64-linux-android-ar` installed?
error: `cargo rustc --lib --message-format=json-render-diagnostics --manifest-path src/rust/Cargo.toml --release -v --features pyo3/extension-module --crate-type cdylib --` failed with code 101
      [end of output]

  note: This error originates from a subprocess, and is likely not a problem with pip.
  ERROR: Failed building wheel for cryptography

Apple 2FA not supported?

I've got 2FA enabled for my Apple account and when pypush asks for it I get this after entering the (2FA) code:

Traceback (most recent call last):
  File "/pypush/./demo.py", line 341, in <module>
    trio.run(main, args)
  File "/usr/local/lib/python3.11/dist-packages/trio/_core/_run.py", line 2251, in run
    raise runner.main_task_outcome.error
  File "/pypush/./demo.py", line 244, in main
    users.append(ids.IDSAppleUser.authenticate(conn, username, password))
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/pypush/ids/__init__.py", line 65, in authenticate
    user_id, auth_token = profile.get_auth_token(username, password, factor_callback)
                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/pypush/ids/profile.py", line 64, in get_auth_token
    raise Exception(f"Error: {result}")
Exception: Error: {'message': 'SED:3:VEN-PROD:43aa8e34-ba49-40f5-80f5-e414fe93fb55:432f9f65-bbb9-4aae-b54f-86f2f179292c:1702051751:b67a06b0-7d01-4172-84e2-42c1297a2df0:9a29965493c79209a82f585c6d278c60e87216be5b90dc433a78673066c314aa:EM', 'status': 5012}

By the way I am using the sms-forwarding branch under Debian.

Doesn't work on newer versions of Python

(base) bryan@Bryans-MacBook-Pro-7 pypush % python3 demo.py
Traceback (most recent call last):
  File "demo.py", line 13, in <module>
    import apns
  File "/Users/bryan/work/pypush/apns.py", line 12, in <module>
    import tlslite
  File "/Users/bryan/miniconda3/lib/python3.8/site-packages/tlslite/__init__.py", line 27, in <module>
    from tlslite.api import *
  File "/Users/bryan/miniconda3/lib/python3.8/site-packages/tlslite/api.py", line 11, in <module>
    from .tlsconnection import TLSConnection
  File "/Users/bryan/miniconda3/lib/python3.8/site-packages/tlslite/tlsconnection.py", line 71
    async=False):
    ^
SyntaxError: invalid syntax

Add support for named group chats

I have a group chat with two people that has a name and group chat photo. I used pypush to text these two people (made sure that the phone numbers and everything matched), and it made a new group chat rather than texting into the existing one.

Participant identities being mistaken as fake accounts

Hey,

I have two Apple Id users connected to each their email, and have them setup on two seperate Apple product.

I am able to use IMessage to send messages between the two devices. This worked fine with this project on the 26th of November as well, however when i returned to attempt to test it again now i get an error.

imessage.py:566 mailto:****@duck.com has no identities, this is probably not a real account
imessage.py:566 mailto:****@gmail.com has no identities, this is probably not a real account

This is from the async branch as suggested by @Cypheriel on the issue #74.

Do you guys have a stable branch or working version that i can use to develop? 🤞🏽

wont run demo.py 'type' object is not subscriptable

installed all requirements

ran the command , python37 demo.py

error

Traceback (most recent call last):
File "demo.py", line 13, in
import apns
File "F:\Users\x\Documents\imessage api\pypush-main\apns.py", line 17, in
import albert
File "F:\Users\x\Documents\imessage api\pypush-main\albert.py", line 48, in
def generate_push_cert() -> tuple[str, str]:
TypeError: 'type' object is not subscriptable

Send madrid 130 messages to indicate there is updated registration information

Messages with type 130 are sent to devices to notify them that there is updated registration information for them to look up.
This is for both:

  • Other accounts, so that they know to send messages to the newly added device
  • Devices on your own account, so that they can forward to other people that they know about

This would also work around a current issue in Beeper's new bridge, where it does not notice that a phone number was linked with pypush, because it only listens for the 130 (that we do not send) and does not see the ids sign in notification sent by Apple (that real iMessage and the old bridge noticed).

Validation data expired

I tried to update data.plist, but I got a raise Exception("Validation data expired! ") Could you please help me solve this headache?
Also, how do I create a batch data.plist, or make it update automatically

Unable to find the public key of the sender, cannot verify

[16:36:07] WARNING Unable to find the public key of the sender, cannot verify imessage.py:404
Traceback (most recent call last):
File "/Volumes/Code/play/pypush/./demo.py", line 158, in
msg = im.receive()
^^^^^^^^^^^^
File "/Volumes/Code/play/pypush/imessage.py", line 436, in receive
raise Exception("Failed to verify payload")
Exception: Failed to verify payload

ModuleNotFoundError: No module named 'rich'

(Apple Silicon. I'll try on x86 Linux)

git clone https://github.com/JJTech0130/pypush
pip3 install -r requirements.txt
python3 ./demo.py

❯❯python3 ./demo.py
Traceback (most recent call last):
File "/Users/faucherd/Downloads/pypush/./demo.py", line 11, in
from rich.logging import RichHandler
ModuleNotFoundError: No module named 'rich'

Verify TLS certificates

Apple's certificates are self-signed, so we currently just don't verify them. Eventually we would like to verify them properly.

No cert in response

For the last few days, I've been getting a new error. Any idea what could be the issue or how I could fix this?

./reregister
/opt/pypush /opt/pypush
[11:36:31] INFO     Connected to APNs (33-courier.push.apple.com)                                                                                                                                                                  apns.py:191
           DEBUG    Restoring new-style identity...                                                                                                                                                                                demo.py:200
[11:36:33] INFO     Generated validation data                                                                                                                                                                                       nac.py:415
Traceback (most recent call last):
  File "/opt/pypush/demo.py", line 340, in <module>
    trio.run(main, args)
  File "/opt/pypush/.venv/lib/python3.11/site-packages/trio/_core/_run.py", line 2093, in run
    raise runner.main_task_outcome.error
  File "/opt/pypush/demo.py", line 295, in main
    await reregister(conn, users)
  File "/opt/pypush/demo.py", line 125, in reregister
    register(conn, users)
  File "/opt/pypush/demo.py", line 105, in register
    users = ids.register(conn, users, vd, args.client_data or args.reg_notify)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/pypush/ids/__init__.py", line 136, in register
    certs = identity.register(
            ^^^^^^^^^^^^^^^^^^
  File "/opt/pypush/ids/identity.py", line 187, in register
    raise Exception(f"No cert in response: {r}")
Exception: No cert in response: {'services': [{'service': 'com.apple.madrid', 'users': [{'user-id': '<REDACTED>', 'message': '<REDACTED', 'status': 6001}, {'uris': [{'uri': '<REDACTED>', 'status': 0}, {'uri': '<REDACTED>', 'status': 0}], 'user-id': '<REDACTED>', 'cert': b'<REDACTED>', 'status': 0}], 'status': 0}], 'status': 0}

However it looks like there is a cert field in the response body. I've removed it here for privacy reasons but it's a string of bytes.

I'm on commit f205e86bdf1a4ea5414a78985721c721039ada97 of the sms-registration branch.

Missing iMessage features

This is a list of iMessage features that are too simple for their own issue and we're missing

  • typing indicators
  • read receipts
  • unsending messages
  • editing messages
  • replies

TODO: add more stuff here

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.