An experimental design for a privacy-minded push server.
You will need to install MongoDB using the package manager of your choice:
On Mac OS X, I recommend Homebrew:
$ brew install mongodb
Or on Ubuntu:
$ apt-get install mongodb
If you don't have Python and pip, get them.
$ easy_install pip
Setup your virtual environment. You'll probably need to do some more stuff too.
$ pip install virtualenv virtualenvwrapper
$ mkvirtualenv cps
$ workon cps
You will need to install the following dependencies: apns
, flask
, pymongo
, requests
, pycrypto
, python-dateutil
(cps)$ pip install apns flask pymongo requests pycrypto python-dateutil
Download your SSL cert(s) from the Apple Provisioning Portal and convert them to the PEM format and put them in the private_keys
directory:
$ openssl x509 -in ChatSecureDevCert.cer -inform der -out ChatSecureDevCert.pem
$ openssl pkcs12 -nocerts -out ChatSecureDevKey.pem -in ChatSecureDevKey.p12
Create secrets.py
and fill in values for the iap_shared_secret
(from iTunes Connect) and transaction_id_salt
.
Start MongoDB:
$ mongod
Launch the Push Server:
$ workon cps
$ python chatsecure_push.py
To send a push to an account_id
(don't forget your pat
!):
$ curl -v -H "Content-Type: application/json" -X POST -d '{"pat":"1975460","account_id":"9846905"}' https://push.chatsecure.org/knock
Device Push Token (DPT): Unique (possibly changing) device token returned from iOS device. This is used by APNs to send messages to a specific endpoint.
Push Access Token (PAT): Generated by our server, linked to an account ID, acts as a whitelist.
APNs: Apple Push Notification Service
Receipt: In-App Purchase Receipt
{
account: {
"account_id": "randomly assigned account ID"
"password": "hashed global account password",
"dpt": ["32 bytes of hex in string format", "This is returned from the iOS device"],
"pat": ["randomly generated push access tokens"],
"transaction_id": "hashed original transaction id from IAP receipt",
"purchase_date": "date of original purchase",
"expiration_date": "date of account expiration"
}
}
All server functions take a JSON dictionary as input.
register(receipt, reset=false)
- Verifies In-App Purchase receipt with Apple before account creation
- Creates
account_id
andpassword
in database - If
reset
istrue
, the oldaccount_id
is deleted and a newaccount_id
andpassword
are created
change_password(account_id, password, new_password)
- Changes password
request_product_identifiers(store=iOS)
- Returns array of IAP product identifiers for chosen App Store
add_dpt(account_id, password, dpt)
- Updates the device push token for a user
request_pat(account_id, password)
- Returns a new push access token
list_pat(account_id, password)
- Returns a list of the currently active PATs
block_pat(account_id, password, pat)
- Removes a PAT from list of active PATs, removing it from the whitelist.
knock(account_id, pat, anonymous=false)
- Sends push message to active
dpt
associated withaccount_id
- Only sent if
pat
is in theaccount_id
's whitelist - If
anonymous
istrue
, don't sendpat
in push message.
- Sends push message to active
ChatSecure Push Server
Copyright (C) 2012 Chris Ballinger
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.