diff --git a/README.md b/README.md index b979d6b..972839a 100644 --- a/README.md +++ b/README.md @@ -22,18 +22,84 @@ In order for Apple to verify your number, a specialized message has to be sent f Make sure you have git and Python installed. 1. `git clone -b sms-registration https://github.com/beeper/pypush` -2. `cd pypush` , `python3 -m pip install -r requirements.txt` +2. `cd pypush` -# Number Registration +# Number Registration on Linux/MacOS +It is *strongly* recommended to use a Python virtual environment to setup Pypush. This ensures changes in your system's Python installation does not +break compatibility with Pypush with system updates. -1. `python3 demo.py --phone [ip]`. Replace `ip` with your phone's local IP. *(Usually this starts with `192.168.x.x`, however it can also start with `172` or `10`.)* -2. If the previous command ran successfully, you can now run `python3 demo.py --reregister` +1. If you do not already have a directory where Python virtual environments are located then +create a directory for your Python virtual environment. If you already have one then skip this step. +Virtual environments are traditionally placed in a hidden folder in your home directory on Linux/MacOS. +It can be created anywhere you wish. These instructions will assume you created it in your home directory. +``` +mkdir ~/.venv +``` +2. Create a virtual environment using Python 3.10: +``` +python3.10 -m venv ~/.venv/pypush +``` +3. Activate the virtual environment: +``` +source ~/.venv/pypush/bin/activate +``` +4. Install the required packages using pip: +``` +pip install -r requirements.txt +``` +5. Run the demo script, replacing `[ip]` with your phone's local IP address: +``` +python demo.py --phone [ip] +``` +# Number reregistration option 1, automatic reregistration +Automatic reregistration is handled by determining when your imessage registration certificate expires +and reregistering 5 minutes before expiration. Put the following in a text file and save as `pypush_reregister.sh` in your home directory: +``` +#!/bin/bash +cd /path/to/pypush +source ~/.venv/pypush/bin/activate +python ./demo.py --daemon +``` +1. Make the reregistration script executable: +``` +chmod +x ~/pypush_reregister.sh +``` +2. Use [Screen](https://www.gnu.org/software/screen/manual/screen.html) to easily monitor reregistration status and set to run on boot, replacing "user" with your username: +``` +@reboot sleep 60;screen -S pypush -d -m /home/user/pypush_reregister.sh > /dev/null 2>&1 +``` +3. Reboot + +The basics of using screen are outlined below but this is not intended to be a tutorial in using screen. In order to see a more complete +guid please visit the following [guide](https://linuxize.com/post/how-to-use-linux-screen/). To monitor the status of registration you can +connect to the virtual screen you created. +``` +$ screen -r pypush +``` +To disconnect from the virtual screen press ctrl+a d. + +# Number reregistration option 2, registration every 30 minutes +Put the following in a text file and save as `pypush_reregister.sh` in your home directory: +``` +#!/bin/bash +cd /path/to/pypush +source ~/.venv/pypush/bin/activate +python ./demo.py --reregister +``` +1. Make the reregistration script executable: +``` +chmod +x ~/pypush_reregister.sh +``` +2. To automatically reregister every 30 minutes, execute the following: +```crontab -e +``` +3. Add the following to your crontab file, replacing "user" with your username: +``` +*/30 * * * * /home/user/pypush_reregister.sh +``` ***Please note:*** This last script is the script you will be running continuously. We recommend every 30 minutes. -### Automatic registration -There should also be a file called `reregister.py`, if you run this it should reregister you every 30 minutes. You can edit this file to rerun at any other interval. You can also use a cronjob to do this task for you in a more streamlined way if you are more familiar with IT. - ### Good to Know You will have to reregister your number every so often. This can last anywhere between 10 minutes to 48 hours, and *usually* the longer you run the script, the longer it takes to deregister. We may implement a feature to automatically detect deregistration in the future. diff --git a/demo.py b/demo.py index 3847059..7de1595 100644 --- a/demo.py +++ b/demo.py @@ -3,6 +3,7 @@ import logging import os import threading import time +import traceback from base64 import b64decode, b64encode from getpass import getpass from cryptography import x509 @@ -238,6 +239,25 @@ async def main(args: argparse.Namespace): logging.info("Reregistered!") + if args.cronreg: + reregister_within = 60 # Minutes, time where if expiration time is less than, rereg. + for user in users: + if "P:" in str(user.user_id): + # logging.info(f'The user is: {user}') + cert = x509.load_pem_x509_certificate(user.id_cert.encode('utf-8')) + expiration = cert.not_valid_after + logging.info(f'Certificate expires on: {expiration}') + reregister_time = expiration - datetime.timedelta(minutes=reregister_within) + reregister_time = reregister_time.astimezone(datetime.timezone.utc) + logging.info(f'Reregistration will occur at: {reregister_time}') + reregister_delta = (reregister_time - datetime.datetime.now(datetime.timezone.utc)).total_seconds() + logging.info(f'The time between now and reregistration time is: {(reregister_delta / 3600):.2f} hours or {(reregister_delta / 86400):.2f} days') + if reregister_delta > 3600: + logging.info('Certificates expiration is greater than 60 minutes, quiting') + else: + logging.info('Certificate expires soon, reregistering now') + expiration = await reregister(conn, users) + logging.info('Reregistered') elif args.reregister: await reregister(conn, users) @@ -273,6 +293,7 @@ if __name__ == "__main__": parser.add_argument("--phone", type=str, help="Override the phone IP") parser.add_argument("--gateway", type=str, help="Override the gateway phone number") parser.add_argument("--daemon", action="store_true", help="Continuously reregister 5 minutes before the certificate expires") + parser.add_argument("--cronreg", action="store_true", help="Reregister if less than 60 minutes from expiration") args = parser.parse_args() diff --git a/unix_installer.sh b/unix_installer.sh new file mode 100644 index 0000000..e1b6b63 --- /dev/null +++ b/unix_installer.sh @@ -0,0 +1,54 @@ +#!/bin/bash + +set -o +set -x +set -u + +OS_NAME=$(uname -s) + +if [[ "$OS_NAME" == "Darwin" ]]; then + echo "The operating system is macOS." + if command -v brew >/dev/null 2>&1; then + echo "Homebrew is already installed." + else + /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" + fi + brew install cmake + brew install pkgconfig +elif [[ "$OS_NAME" == "Linux" ]]; then + echo "The operating system is Linux." +else + echo "Unknown operating system: $OS_NAME" +fi + +# Create a virtual environment +mkdir -p ~/.venv +python3.10 -m venv ~/.venv/pypush +source ~/.venv/pypush/bin/activate + +# Clone the repo +cd ~ +git clone -b sms-registration https://github.com/beeper/pypush +cd pypush + +# Prompt the user for the IP address of their phone. +read -p "Enter the IP address of your phone: " PHONEIP + +# Execute the `python demo.py` script with the phone IP address passed as a parameter. +python demo.py --phone $PHONEIP + +# Create a reregistration script +cat > reregister.sh <