Merge branch 'headers-fix' into 'master'

Include the headers required by mastodon

See merge request pleroma/relay!23
This commit is contained in:
Haelwenn 2020-11-12 13:40:20 +00:00
commit 6e10db1aa0
2 changed files with 25 additions and 17 deletions

View file

@ -6,12 +6,17 @@ import uuid
import re import re
import simplejson as json import simplejson as json
import cgi import cgi
import datetime
from urllib.parse import urlsplit from urllib.parse import urlsplit
from Crypto.PublicKey import RSA from Crypto.PublicKey import RSA
from cachetools import LFUCache
from . import app, CONFIG
from .database import DATABASE from .database import DATABASE
from .http_debug import http_debug from .http_debug import http_debug
from .remote_actor import fetch_actor
from cachetools import LFUCache from .http_signatures import sign_headers, generate_body_digest
# generate actor keys if not present # generate actor keys if not present
@ -29,19 +34,12 @@ if "actorKeys" not in DATABASE:
PRIVKEY = RSA.importKey(DATABASE["actorKeys"]["privateKey"]) PRIVKEY = RSA.importKey(DATABASE["actorKeys"]["privateKey"])
PUBKEY = PRIVKEY.publickey() PUBKEY = PRIVKEY.publickey()
sem = asyncio.Semaphore(500)
from . import app, CONFIG
from .remote_actor import fetch_actor
AP_CONFIG = CONFIG['ap'] AP_CONFIG = CONFIG['ap']
CACHE_SIZE = CONFIG.get('cache-size', 16384) CACHE_SIZE = CONFIG.get('cache-size', 16384)
CACHE = LFUCache(CACHE_SIZE) CACHE = LFUCache(CACHE_SIZE)
sem = asyncio.Semaphore(500)
async def actor(request): async def actor(request):
data = { data = {
@ -68,11 +66,6 @@ async def actor(request):
app.router.add_get('/actor', actor) app.router.add_get('/actor', actor)
from .http_signatures import sign_headers
get_actor_inbox = lambda actor: actor.get('endpoints', {}).get('sharedInbox', actor['inbox']) get_actor_inbox = lambda actor: actor.get('endpoints', {}).get('sharedInbox', actor['inbox'])
@ -86,10 +79,14 @@ async def push_message_to_actor(actor, message, our_key_id):
'(request-target)': 'post {}'.format(url.path), '(request-target)': 'post {}'.format(url.path),
'Content-Length': str(len(data)), 'Content-Length': str(len(data)),
'Content-Type': 'application/activity+json', 'Content-Type': 'application/activity+json',
'User-Agent': 'ActivityRelay' 'User-Agent': 'ActivityRelay',
'Host': url.netloc,
'Digest': 'SHA-256={}'.format(generate_body_digest(data)),
'Date': datetime.datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT')
} }
headers['signature'] = sign_headers(headers, PRIVKEY, our_key_id) headers['signature'] = sign_headers(headers, PRIVKEY, our_key_id)
headers.pop('(request-target)') headers.pop('(request-target)')
headers.pop('Host')
logging.debug('%r >> %r', inbox, message) logging.debug('%r >> %r', inbox, message)

View file

@ -55,6 +55,17 @@ def sign_signing_string(sigstring, key):
return SIGSTRING_CACHE[sigstring] return SIGSTRING_CACHE[sigstring]
def generate_body_digest(body):
bodyhash = SIGSTRING_CACHE.get(body)
if not bodyhash:
h = SHA256.new(body.encode('utf-8'))
bodyhash = base64.b64encode(h.digest()).decode('utf-8')
SIGSTRING_CACHE[body] = bodyhash
return bodyhash
def sign_headers(headers, key, key_id): def sign_headers(headers, key, key_id):
headers = {x.lower(): y for x, y in headers.items()} headers = {x.lower(): y for x, y in headers.items()}
used_headers = headers.keys() used_headers = headers.keys()