Skip to content
This repository has been archived by the owner on Jul 13, 2023. It is now read-only.

Commit

Permalink
bug: do not require encryption header for APNs aes128gcm encoded …
Browse files Browse the repository at this point in the history
…messages (#1385)

* bug: do not require `encryption` header for APNs `aes128gcm` encoded messages

Includes better logging for uncaught APNs errors, since those were
getting dropped by cyclone.

Issue #1383
Closes #1384
  • Loading branch information
jrconlin authored May 7, 2020
1 parent e531cdd commit 148781c
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 11 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ ENV PATH=$PATH:/root/.cargo/bin

RUN \
apt-get update && \
apt-get install -y -qq libexpat1-dev gcc libssl-dev libffi-dev libjemalloc1 && \
apt-get install -y -qq libexpat1-dev gcc libssl-dev libffi-dev libjemalloc2 && \
make clean && \
pip install -r requirements.txt && \
pypy setup.py develop
Expand Down
23 changes: 14 additions & 9 deletions autopush/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,21 @@ def write_error(self, code, **kwargs):
websocket.
"""
self.set_status(code)
if 'exc_info' in kwargs:
try:
self.set_status(code)
if 'exc_info' in kwargs:
self.log.failure(
format=kwargs.get('format', "Exception"),
failure=failure.Failure(*kwargs['exc_info']),
client_info=self._client_info)
else:
self.log.failure("Error in handler: %s" % code,
client_info=self._client_info)
self.finish()
except Exception as ex:
self.log.failure(
format=kwargs.get('format', "Exception"),
failure=failure.Failure(*kwargs['exc_info']),
client_info=self._client_info)
else:
self.log.failure("Error in handler: %s" % code,
client_info=self._client_info)
self.finish()
"error in write_error: {}:{} while printing {};{}".format(
code, ex, kwargs, self._client_info))

def authenticate_peer_cert(self):
"""Authenticate the client per the configured client_certs.
Expand Down
3 changes: 2 additions & 1 deletion autopush/router/apnsrouter.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,9 @@ def _route(self, notification, router_data):
if notification.data:
payload["body"] = notification.data
payload["con"] = notification.headers["encoding"]
payload["enc"] = notification.headers["encryption"]

if "encryption" in notification.headers:
payload["enc"] = notification.headers["encryption"]
if "crypto_key" in notification.headers:
payload["cryptokey"] = notification.headers["crypto_key"]
elif "encryption_key" in notification.headers:
Expand Down
76 changes: 76 additions & 0 deletions autopush/tests/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -2363,6 +2363,82 @@ def test_registration(self):
"SentTab.NoTabArrivingNotification.title"
assert ca_data['body'] == base64url_encode(data)

@inlineCallbacks
def test_apns_aesgcm_registration_bad(self):
self._add_router()
# get the senderid
url = "{}/v1/{}/{}/registration".format(
self.ep.conf.endpoint_url,
"apns",
"firefox",
)
response, body = yield _agent('POST', url, body=json.dumps(
{"token": uuid.uuid4().hex}
))
assert response.code == 200
jbody = json.loads(body)

# Send a fake message
data = ("\xa2\xa5\xbd\xda\x40\xdc\xd1\xa5\xf9\x6a\x60\xa8\x57\x7b\x48"
"\xe4\x43\x02\x5a\x72\xe0\x64\x69\xcd\x29\x6f\x65\x44\x53\x78"
"\xe1\xd9\xf6\x46\x26\xce\x69")
crypto_key = ("keyid=p256dh;dh=BAFJxCIaaWyb4JSkZopERL9MjXBeh3WdBxew"
"SYP0cZWNMJaT7YNaJUiSqBuGUxfRj-9vpTPz5ANmUYq3-u-HWOI")
content_encoding = "aesgcm"

response, body = yield _agent(
'POST',
str(jbody['endpoint']),
headers=Headers({
"crypto-key": [crypto_key],
"ttl": ["0"],
"content-encoding": [content_encoding],
}),
body=data
)
assert response.code == 400

@inlineCallbacks
def test_apns_registration_aes128gcm(self):
self._add_router()
# get the senderid
url = "{}/v1/{}/{}/registration".format(
self.ep.conf.endpoint_url,
"apns",
"firefox",
)
response, body = yield _agent('POST', url, body=json.dumps(
{"token": uuid.uuid4().hex}
))
assert response.code == 200
jbody = json.loads(body)

# Send a fake message

data = ("\xa2\xa5\xbd\xda\x40\xdc\xd1\xa5\xf9\x6a\x60\xa8\x57\x7b\x48"
"\xe4\x43\x02\x5a\x72\xe0\x64\x69\xcd\x29\x6f\x65\x44\x53\x78"
"\xe1\xd9\xf6\x46\x26\xce\x69")
content_encoding = "aes128gcm"

response, body = yield _agent(
'POST',
str(jbody['endpoint']),
headers=Headers({
"ttl": ["0"],
"content-encoding": [content_encoding],
}),
body=data
)
ca_data = json.loads(
self._mock_connection.request.call_args[1]['body'])
assert response.code == 201
# ChannelID here MUST match what we got from the registration call.
# Currently, this is a lowercase, hex UUID without dashes.
assert ca_data['chid'] == jbody['channelID']
assert ca_data['con'] == content_encoding
assert ca_data['body'] == base64url_encode(data)
assert 'enc' not in ca_data

@inlineCallbacks
def test_registration_no_token(self):
self._add_router()
Expand Down

0 comments on commit 148781c

Please sign in to comment.