commit 37c7ae2c9ebf14e9b840d9880aa565fc1c10d6fa Author: Maxime “pep” Buquet Date: Fri Aug 26 17:33:36 2022 +0200 Initial commit Signed-off-by: Maxime “pep” Buquet diff --git a/aesgcm-dl.py b/aesgcm-dl.py new file mode 100755 index 0000000..618916c --- /dev/null +++ b/aesgcm-dl.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# vim:fenc=utf-8 et ts=4 sts=4 sw=4 +# +# Copyright © 2022 Maxime “pep” Buquet +# +# This file is licensed under AGPL-3.0-or-later + +""" + AESGCM URIs downloader +""" + +import sys +import asyncio +from io import BytesIO +from pathlib import Path + +from aiohttp import ClientSession +from slixmpp.version import __version__ as slixmpp_version +from slixmpp.plugins.xep_0454 import XEP_0454 + + +class InvalidURI(Exception): + """Raised when an invalid aesgcm URI is specified""" + + def __init__(self, url) -> None: + self.url = url + + +async def handle_file(uri: str) -> None: + """Downloads, decrypts, and writes specified URI""" + + try: + aesurl, fragment = uri.rsplit('#', 1) + except ValueError as exn: + raise InvalidURI(uri) from exn + + url = aesurl.replace('aesgcm://', 'https://') + filename = Path(url.rsplit('/', 1)[1]) + + async with ClientSession(headers={'User-Agent': 'slixmpp ' + slixmpp_version}) as session: + async with session.get(url) as response: + print(f'Got response for {url}') + input_file = BytesIO(await response.read()) + + with filename.open('wb') as file: + print(f'Writing to {filename}') + file.write(XEP_0454.decrypt(input_file, fragment)) + + +if __name__ == '__main__': + if len(sys.argv) != 2: + print('usage: aesgcm-dl ', file=sys.stderr) + sys.exit(1) + + try: + asyncio.run(handle_file(sys.argv[1])) + except InvalidURI as exn: + print(f'Invalid aesgcm URI: {exn.url}', file=sys.stderr) + sys.exit(2)