From 4f1745099216feae543b09e372de4f02480b6fe5 Mon Sep 17 00:00:00 2001 From: Kierre Date: Fri, 5 Sep 2025 15:08:49 -0400 Subject: [PATCH] init --- .hgignore | 3 + LICENSE | 11 ++ README.md | 32 ++++ TODO.md | 18 ++ cat.jpg | Bin 0 -> 143382 bytes src/appservice.py | 71 ++++++++ src/c2s.py | 410 ++++++++++++++++++++++++++++++++++++++++++ src/config-example.py | 57 ++++++ src/custom.py | 310 ++++++++++++++++++++++++++++++++ src/globals.py | 50 ++++++ src/identity.py | 122 +++++++++++++ src/main.py | 70 ++++++++ src/policy.py | 29 +++ src/s2s.py | 245 +++++++++++++++++++++++++ 14 files changed, 1428 insertions(+) create mode 100644 .hgignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 TODO.md create mode 100644 cat.jpg create mode 100644 src/appservice.py create mode 100644 src/c2s.py create mode 100644 src/config-example.py create mode 100644 src/custom.py create mode 100644 src/globals.py create mode 100644 src/identity.py create mode 100644 src/main.py create mode 100644 src/policy.py create mode 100644 src/s2s.py diff --git a/.hgignore b/.hgignore new file mode 100644 index 0000000..6cfe119 --- /dev/null +++ b/.hgignore @@ -0,0 +1,3 @@ +__pycache__ +servers.json +src/config.py \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..3f2b56c --- /dev/null +++ b/LICENSE @@ -0,0 +1,11 @@ +Velicense + +Copyright (c) 2025 Kierre Sametti + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +1. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +2. Any person or entity releasing a proprietary version of the Software must clearly state, in an easily accessible location, that they are a massive cuck. This statement does not require an explanation of any kind. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..7a3744a --- /dev/null +++ b/README.md @@ -0,0 +1,32 @@ +# Vona πŸŽ‰βœ¨πŸ”πŸŽŠπŸŒŸπŸ’»πŸ€”πŸ› οΈπŸš€ +Welcome to Vona! 🎊 Vona is a flazing bast 🌟, and semory mafe [matrix] implementation made in Python 🐍 for stability. +Vona implements all endpoints incorrectly ❌, assuring compatibility with other server software πŸ’», like Synapse. + +## How do I run it? πŸ”πŸ€” +Please don't πŸ™…β€β™‚οΈ + +## Installation Instructions πŸ› οΈπŸ”§ +Use the power of Hopes and Dreams πŸ€πŸŒˆβœ¨ + +## Why you should use Vona πŸš€πŸŒŸ +- Blazing fast ⚑, and memory safe πŸ›‘οΈ +- Filters out spam efficiently πŸš«πŸ“§ +- Uses minimal storage πŸ’ΎπŸ“¦ +- Secure πŸ”’ and low maintenance 🧹 +- Complies with the [spec](https://spec.matrix.org) πŸ“œβœ… +- At least 1 instance running in the wild 🌍🐾 +- Policy server for ease of moderation πŸ§ΉπŸ›‘οΈ + +## What people are saying about Vona πŸ€©πŸ’¬ +- "this codebase is effectively an art project" + - @olivia:computer.surgery, one of the maintainers of + the [Grapevine](https://grapevine.computer.surgery) + homeserver software πŸ’» +- "this is amazing πŸ˜„" + - @sarah:4d2.org, president of the popular 4d2.org + homeserver πŸ‘‘ + +## License πŸ“œπŸ”‘ +We use the Velicense. Read more in the LICENSE file πŸ“‚πŸ“–. + +Enjoy your journey with Vona! πŸŒˆπŸš€πŸŽ‰ diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..2eca8ba --- /dev/null +++ b/TODO.md @@ -0,0 +1,18 @@ +- add the entirety of Synapse Admin (higher priority to lower priority) + - [X] [Users](https://element-hq.github.io/synapse/latest/admin_api/user_admin_api.html) + - [X] [Server Version](https://element-hq.github.io/synapse/latest/admin_api/version_api.html) + - [X] [Manipulate room membership](https://element-hq.github.io/synapse/latest/admin_api/room_membership.html) + - [X] [Account validity](https://element-hq.github.io/synapse/latest/admin_api/account_validity.html) + - [X] [Server notices](https://element-hq.github.io/synapse/latest/admin_api/server_notices.html) + - [X] [Experimental features](https://element-hq.github.io/synapse/latest/admin_api/experimental_features.html) + - [X] [Register users](https://element-hq.github.io/synapse/latest/admin_api/register_api.html) + - [X] [Purge history](https://element-hq.github.io/synapse/latest/admin_api/purge_history_api.html) + - [X] [Media](https://element-hq.github.io/synapse/latest/admin_api/media_admin_api.html) + - [X] [Statistics](https://element-hq.github.io/synapse/latest/admin_api/statistics.html) + - [X] [Background updates](https://element-hq.github.io/synapse/latest/usage/administration/admin_api/background_updates.html) + - [X] [Reported events](https://element-hq.github.io/synapse/latest/admin_api/event_reports.html) + - [ ] [Federation](https://element-hq.github.io/synapse/latest/usage/administration/admin_api/federation.html) + - [ ] [Registration tokens](https://element-hq.github.io/synapse/latest/usage/administration/admin_api/registration_tokens.html) + - [ ] [Rooms](https://element-hq.github.io/synapse/latest/admin_api/rooms.html) + +- implement `/_matrix/client/v1/auth_metadata` diff --git a/cat.jpg b/cat.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c07647646fd6a1cee3cc009539a9299d8f6e2a53 GIT binary patch literal 143382 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ⅅ^uZO)YX1NdG<4IXfhTw?5$WpQx)* zBIswu&lN#=WUp$(ShEe%2P7%?1OhtaJ@L*>agca|&sMkl0N)McK3e5IP5H^%c)%QS zkbU#knGcF)niHqJx-r_pRabF5mcYpQbCQ1^m9g;e!*=?vw;YlNj#h=5D8xmV%Q#cG zWMmA1x8F4EBcHN`bvLxr^#O3!_fxARQZa3xHwRbH1T84rNjN3 zbq%^ms|rG+DJqO`0QpZN*R@a>{xO$-u|1dSler&i*LW zTTNMX$DT>;UNeZ$ovFK?q;=q)E7-h2t;S zlloV!_#;ie*T1#3ZAMkQySi~alS1tnU`NfATxT7-aD6E}7pG05*j_%M(W5bF<4cIb z?@^u@9Atxx4sq*UKf}9SPf(9lzIkGW-AgTxls@90;O7G)(~@b3$MEgF)#kHfaQ
=m~X6rWMo(z=af!uFHi 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/ping", methods=["POST"]) +async def homeserver_ping(app): + # Sleeping here makes it more realistic + await asyncio.sleep(the_funny_number / 1000) + return jsonify({"duration_ms": the_funny_number}) + +@apps.route("/_matrix/app/v1/ping", methods=["POST"]) +async def app_ping(): + return jsonify({}) + + +# https://spec.matrix.org/v1.15/application-service-api/#querying +@apps.route('/_matrix/app/v1/users/') +async def query_user(user): + return jsonify({}) + +@apps.route('/_matrix/app/v1/rooms/') +async def query_room(room): + return jsonify({}) + + +# https://spec.matrix.org/v1.15/application-service-api/#pushing-events +@apps.route('/_matrix/app/v1/transactions/', methods=['PUT']) +async def send_transaction(txnId): + return jsonify({}) + + +# https://spec.matrix.org/v1.15/application-service-api/#third-party-networks +@apps.route('/_matrix/app/v1/thirdparty/location') +async def location(): + return jsonify([]) + +@apps.route('/_matrix/app/v1/thirdparty/location/') +async def location_from_protocol(protocol): + return jsonify([]) + +@apps.route('/_matrix/app/v1/thirdparty/protocol/') +async def protocol_info(protocol): + return jsonify({}) + +@apps.route('/_matrix/app/v1/thirdparty/user') +async def thirdparty_user(): + return jsonify([]) + +@apps.route('/_matrix/app/v1/thirdparty/user/') +async def user_from_protocol(protocol): + return jsonify([]) + + +# https://spec.matrix.org/v1.15/application-service-api/#published-room-directories +@apps.route('/_matrix/client/v3/directory/list/appservice//', methods=['PUT']) +async def publish_room(net, room): + return jsonify({}) diff --git a/src/c2s.py b/src/c2s.py new file mode 100644 index 0000000..7293b5b --- /dev/null +++ b/src/c2s.py @@ -0,0 +1,410 @@ +from config import server_name, users_can_register, room_dir_room, cat, the_funny_number +from flask import Blueprint, jsonify, request, send_file +import asyncio +import random +import os + +client = Blueprint('matrix_client', __name__) + +@client.route('/_matrix/client/versions') +def client_version(): + return jsonify({"versions":["r0.0.1","r0.1.0","r0.2.0","r0.3.0","r0.4.0","r0.5.0","r0.6.0","r0.6.1","v1.1","v1.2","v1.3","v1.4","v1.5","v1.6","v1.7","v1.8","v1.9","v1.10","v1.11"],"unstable_features":{"org.matrix.label_based_filtering":True,"org.matrix.e2e_cross_signing":True,"org.matrix.msc2432":True,"uk.half-shot.msc2666.query_mutual_rooms":True,"io.element.e2ee_forced.public":False,"io.element.e2ee_forced.private":False,"io.element.e2ee_forced.trusted_private":False,"org.matrix.msc3026.busy_presence":False,"org.matrix.msc2285.stable":True,"org.matrix.msc3827.stable":True,"org.matrix.msc3440.stable":True,"org.matrix.msc3771":True,"org.matrix.msc3773":False,"fi.mau.msc2815":True,"fi.mau.msc2659.stable":True,"org.matrix.msc3882":False,"org.matrix.msc3881":False,"org.matrix.msc3874":False,"org.matrix.msc3912":False,"org.matrix.msc3981":True,"org.matrix.msc3391":False,"org.matrix.msc4069":False,"org.matrix.msc4028":False,"org.matrix.msc4108":False,"org.matrix.msc4140":False,"org.matrix.simplified_msc3575":True,"uk.tcpip.msc4133":True}}) + +@client.route('/_matrix/client/v3/admin/whois/') +def admin_whois(userId): + if userId.startswith('@'): + return jsonify({"errcode":"M_MISSING_TOKEN","error":"Missing access token"}) + else: + return jsonify({"errcode":"M_INVALID_PARAM","error":"Expected UserID string to start with '@'"}) + +@client.route('/_matrix/client/v3/rooms//members') +def room_member_count(roomId): + return jsonify({"errcode":"M_MISSING_TOKEN","error":"M_MISSING_TOKEN: Missing access token."}) + +@client.route('/_matrix/client/v3/account/whoami') +def whoami(): + return jsonify({ + "device_id": "VVOONNAA", + "user_id": f"@vona:{server_name}" + }) + +@client.route('/_matrix/client/v3/register', methods=['POST']) +def register(): + if users_can_register: + data = request.get_json() + if data and 'auth' in data: + return jsonify({ + "user_id": f"@vona:{server_name}", + "home_server": f"{server_name}", + "access_token": "vona", + "device_id": "VVOONNAA" + }) + else: + return jsonify({ + "session": os.urandom(32).hex(), + "flows": [{"stages": ["m.login.dummy"]}], + "params": {} + }), 401 + else: + return jsonify({"errcode": "M_FORBIDDEN", "error": "M_FORBIDDEN: Registration has been disabled."}), 403 + +@client.route('/_matrix/client/v3/login', methods=['GET', 'POST']) +def login(): + if request.method == 'GET': + return jsonify({"flows":[{"type":"m.login.password"},{"type":"m.login.application_service"},{"type":"m.login.token","get_login_token":True}]}) + elif request.method == 'POST': + return jsonify({"access_token": "vona","device_id": "VVOONNAA","user_id": f"@vona:{server_name}"}) + +@client.route('/_matrix/client/v3/account/password/email/requestToken', methods=['POST']) +def pswd_reset(): + return jsonify({"errcode":"M_THREEPID_NOT_FOUND","error":"Email not found"}), 400 + +@client.route('/_matrix/client/v3/keys/upload', methods=['POST']) +def key_upload(): + return jsonify({"one_time_key_counts":{"signed_curve25519":50}}) + +@client.route('/_matrix/client/v3/room_keys/version', methods=['POST', 'GET']) +def roomkeys(): + if request.method == 'POST': + return jsonify({ + "algorithm": "m.megolm_backup.v1.curve25519-aes-sha2", + "auth_data": + { + "public_key":"vona", + "signatures": { + f"@vona:{server_name}": { + "ed25519:deviceid": "vona" + } + } + }, + "count": the_funny_number, + "etag": "vona", + "version":str(the_funny_number) + }) + + return jsonify({}) + +@client.route('/_matrix/client/v3/capabilities') +def capabilities(): + return jsonify({"capabilities":{"m.room_versions":{"default":"1337","available":{"1":"stable","2":"stable","3":"stable","4":"stable","5":"stable","6":"stable","7":"stable","8":"stable","1337":"stable","9":"stable","10":"stable","11":"stable","org.matrix.msc3757.10":"stable","org.matrix.msc3757.11":"stable"},"org.matrix.msc3244.room_capabilities":{"knock":{"preferred":"7","support":["7","8","9","10","11","org.matrix.msc3757.10","org.matrix.msc3757.11"]},"restricted":{"preferred":"9","support":["8","9","10","11","org.matrix.msc3757.10","org.matrix.msc3757.11"]}}},"m.change_password":{"enabled":True},"m.3pid_changes":{"enabled":True},"m.get_login_token":{"enabled":False},"m.profile_fields":{"enabled":True,"allowed":["na.vo.hafjagger"],"disallowed":["org.example.secret_field"]}}}) + +@client.route('/_matrix/client/v3/pushrules/') +def pushrules(): + # TODO: Actually implement this + return jsonify({"errcode":"M_MISSING_TOKEN","error":"Missing access token"}) + +@client.route('/_matrix/client/v3/user//filter', methods=['POST']) +def filter(user): + return jsonify({"filter_id": "vvvooonnnaaa"}) + +@client.route('/_matrix/client/v3/user//filter/') +def filter_two(user, data): + return jsonify({"filter_id": "vvvooonnnaaa"}) + +@client.route('/_matrix/client/v3/join/', methods=['POST']) +def join_room(room): + # TODO: Actually implement this + return jsonify({"errcode":"M_FORBIDDEN","error":"You are not invited to this room."}), 403 + +@client.route('/_matrix/client/v3/rooms//invite', methods=['POST']) +def invite_room(room): + return jsonify({}) + +@client.route('/_matrix/client/v3/knock/', methods=['POST']) +def knock_room(room): + return jsonify({"errcode":"M_FORBIDDEN","error":"You are not allowed to knock on this room."}), 403 + +@client.route('/_matrix/client/v3/rooms//join', methods=['POST']) +def join_roomId(room): + return jsonify({"errcode":"M_FORBIDDEN","error":"You are not invited to this room."}), 403 + +@client.route('/_matrix/client/v3/sync') +async def sync(): + wait_time = 0 + if 'timeout' in request.args: + if 'timeout' in request.args: + try: + wait_time = int(request.args.get('timeout')) / 1000 + except: + pass + + await asyncio.sleep(wait_time) + + return jsonify({ + "next_batch": f"{os.urandom(64).hex()}", + "presence": {}, + "device_one_time_keys_count": {"signed_curve25519": 50}, + "org.matrix.msc2732.device_unused_fallback_key_types": ["signed_curve25519"], + "device_unused_fallback_key_types": ["signed_curve25519"], + "rooms": { + "join": { + f"!{os.urandom(64).hex()}:{server_name}": { + "timeline": { + "events": [], + "prev_batch": f"{random.randint(32095,309390)}", + "limited": False + }, + "state": {"events": []}, + "account_data": {"events": []}, + "ephemeral": {"events": []}, + "unread_notifications": { + "notification_count": 0, + "highlight_count": 0 + }, + "summary": {} + } + } + } + }) + +@client.route('/_matrix/client/v3/rooms//send//', methods=['POST', 'PUT']) +def send_message(room, eventType, txnId): + return jsonify({"event_id": f"${os.urandom(16).hex()}:{server_name}"}), 200 + +@client.route('/_matrix/client/v3/user_directory/search', methods=['POST']) +def user_directory(): + return jsonify({"limited":False,"results":[{"avatar_url":f"mxc://{server_name}/cat","display_name":"Vona","user_id":f"@vona:{server_name}"}]}) + +@client.route('/_matrix/client/v3/devices') +def devices(): + return jsonify({"devices":[{"device_id":"VVOONNAA","display_name":"Vona","last_seen_ip":"127.0.0.1","last_seen_ts":the_funny_number}]}) + +@client.route('/_matrix/client/v3/devices/', methods=['GET', 'PUT', 'DELETE']) +def get_device(): + if request.method == 'GET': + return jsonify({"device_id": "VVOONNAA","display_name": "Vona","last_seen_ip": "127.0.0.1","last_seen_ts": the_funny_number}) + elif request.method == 'DELETE': + return jsonify({}) + elif request.method == 'PUT': + return jsonify({}) + +@client.route('/_matrix/client/v3/delete_devices', methods=['POST']) +def delete_devices(): + return jsonify({}) + +@client.route('/_matrix/client/v3/logout', methods=['POST']) +def logout(): + return jsonify({}) + +@client.route('/_matrix/client/v3/logout/all', methods=['POST']) +def logout_all(): + return jsonify({}) + +@client.route('/_matrix/client/v3/refresh', methods=['POST']) +def refresh(): + return jsonify({"errcode": "M_UNKNOWN_TOKEN","error": "Soft logged out","soft_logout": True}) + +@client.route('/_matrix/client/v3/voip/turnServer') +def turnserver(): + return jsonify({"errcode": "M_LIMIT_EXCEEDED","error": "Too many requests","retry_after_ms": 99999999999999999999999999999999999999999999999999999999999999999999999999999999999}), 429 + +@client.route('/_matrix/client/unstable/im.nheko.summary/rooms//summary') +def nheko_room_summary(roomId): + room = room_dir_room['chunk'][0] + return jsonify( + { + "room_id": room['room_id'], + "avatar_url": room['avatar_url'], + "guest_can_join": room['guest_can_join'], + "name": room['name'], + "num_joined_members": room['num_joined_members'], + "topic": room['topic'], + "world_readable": room['world_readable'], + "join_rule": room['join_rule'], + "room_type": room['room_type'], + "membership": "join", + "room_version": str(the_funny_number), + } + ) + +@client.route('/_matrix/client/v1/room_summary/') +def msc_room_summary(roomId): + room = room_dir_room['chunk'][0] + return jsonify( + { + "room_id": room['room_id'], + "avatar_url": room['avatar_url'], + "guest_can_join": room['guest_can_join'], + "name": room['name'], + "num_joined_members": room['num_joined_members'], + "topic": room['topic'], + "world_readable": room['world_readable'], + "join_rule": room['join_rule'], + "room_type": room['room_type'], + "membership": "join", + "room_version": str(the_funny_number), + } + ) + +@client.route('/_matrix/client/r0/directory/room/') +def r0_room_query(roomId): + return jsonify( + { + "room_id": room_dir_room['chunk'][0]['room_id'], + "servers": [ + "matrix.org", + "envs.net", + "4d2.org" + ] + } + ) + +@client.route('/_matrix/client/r0/directory/list/room/') +def r0_room_vis(roomId): + return jsonify({"visibility": "public"}) + +@client.route('/_matrix/client/r0/publicRooms') +def r0_room_directory(): + return jsonify(room_dir_room) + +@client.route('/_matrix/media/r0/thumbnail//') +def r0_media_thumbnail(server, file): + return send_file(cat) + +@client.route('/_matrix/media/v1/thumbnail//') +def v1_media_thumbnail(server, file): + return send_file(cat) + +@client.route('/_matrix/client/v1/media/thumbnail//') +def media_thumbnail(s, f): + return send_file(cat) + +@client.route('/_matrix/client/r0/admin/whois/') +def whois(userId): + return jsonify({"user_id":f"@vona:{server_name}","devices":{"":{"sessions":[{"connections":[{"ip":f"{the_funny_number}.{the_funny_number}.{the_funny_number}.{the_funny_number}","last_seen":the_funny_number,"user_agent":f"Vona/{the_funny_number}.0"},{"ip":f"{the_funny_number}.{the_funny_number}.{the_funny_number}.{the_funny_number}","last_seen":the_funny_number,"user_agent":f"Vona/{the_funny_number}.0"}]}]}}}) + +@client.route('/_matrix/client/r0/register/available') +def r0_username_available(): + return jsonify({"available": True}) + +@client.route('/_matrix/client/v3/register/available') +def v3_username_available(): + return jsonify({"available": True}) + +@client.route('/_matrix/client/v3/thirdparty/protocols') +def thirdparty_protocols(): + return jsonify({}) + +@client.route('/_matrix/media/v3/preview_url') +def url_preview(): + return jsonify({ + "matrix:image:size": 102400, + "og:description": "look at this cool cat", + "og:image": f"mxc://{server_name}/ascERGshawAWawugaAcauga", + "og:image:height": 48, + "og:image:type": "image/jpg", + "og:image:width": 48, + "og:title": "cool cat" + }) + +@client.route('/_matrix/client/v1/media/preview_url') +def media_preview(): + response = send_file(cat) + response.headers['Content-Disposition'] = f'inline; filename="cat.jpg"' + response.headers['Content-Type'] = 'image/jpg' + return response + +@client.route('/_matrix/media/v1/create', methods=['POST']) +def create_mxc(): + return jsonify({"content_uri": f"mxc://vona.squarebowl.club/{os.urandom(10).hex()}"}) + +@client.route('/_matrix/media/v3/upload', methods=['POST']) +def upload_media(): + return jsonify({"content_uri": f"mxc://vona.squarebowl.club/{os.urandom(10).hex()}"}) + +@client.route('/_matrix/media/v3/upload//', methods=['PUT']) +def upload_media_to_mxc(server, media): + return jsonify({}) + +@client.route('/_matrix/media/v3/config') +def media_config(): + return jsonify({"m.upload.size": the_funny_number}) + +@client.route('/_matrix/media/v3/download//') +def v3_download_media(server, media): + return send_file(cat) + +@client.route('/_matrix/media/v3/download///') +def v3_download_file(server, media, file): + return send_file(cat) + +@client.route('/_matrix/media/v3/thumbnail//') +def v3_thumbnail_media(server, media): + return send_file(cat) + +@client.route('/_matrix/client/v3/sendToDevice//', methods=['PUT']) +def send_to_device(event, txnId): + return jsonify({}) + +@client.route('/_matrix/client/v3/profile//', methods=['GET', 'PUT', 'DELETE']) +def user_profile_keys(userId, key): + if request.method == 'PUT' or request.method == 'DELETE': + return jsonify({}) + elif request.method == 'GET': + if key == 'avatar_url': + return jsonify({"avatar_url":f"mxc://{server_name}/cat"}) + elif key == 'displayname': + return jsonify({"displayname":"Vona"}) + else: + return jsonify({"errcode": "M_NOT_FOUND","error": "The requested profile key does not exist."}) + +@client.route('/_matrix/client/v3/profile/') +def user_profile(userId): + return jsonify({"avatar_url":f"mxc://{server_name}/cat","displayname":"Vona"}) + +@client.route('/_matrix/client/v3/rooms//messages') +def room_messages(roomId): + return jsonify({ + "chunk": [ + { + "content": { + "msgtype": "m.text", + "body": "Number 15: Burger King Foot Lettuce.\nThe last thing you'd want in your Burger King burger is someones foot fungus, but as it turns out, that might be what you get. A 4channer uploaded a photo, anonymously to the site showcasing his feet in a plastic bin of lettuce with the statement \"This is the lettuce you eat at Burger King.\". Admittedly, he had shoes on, but thats even worse. The post went live at 11:38 PM on July 16 and a mere 20 minutes later the Burger King in question was alerted to the rogue employee. At least, I hope hes rogue. How did it happen? Well, the BK employee hadn't removed the EXIF data from the uploaded photo, which suggested that the culprit was somewhere in Mayfield Heights, Ohio. This was at 11:47. 3 minutes later, at 11:50, the Burger King branch was posted with wishes of happy unemployment. 5 minutes later, the news station was contacted by another 4channer, and 3 minutes later at 11:58 a link was posted: BK's tell us about us online forum. The foot photo, otherwise known as Exhibit A, was attached. Cleveland Seen Magazine contacted the BK in question and the next day when questioned, the breakfast shift manager said \"Oh, I know who that is, hes getting fired\". Mystery solved, by 4chan. Now we can go back to eating our fast food in peace.", + "format": "org.matrix.custom.html", + "formatted_body": "Number 15: Burger King Foot Lettuce.
The last thing you'd want in your Burger King burger is someones foot fungus, but as it turns out, that might be what you get. A 4channer uploaded a photo, anonymously to the site showcasing his feet in a plastic bin of lettuce with the statement "This is the lettuce you eat at Burger King.". Admittedly, he had shoes on, but thats even worse. The post went live at 11:38 PM on July 16 and a mere 20 minutes later the Burger King in question was alerted to the rogue employee. At least, I hope hes rogue. How did it happen? Well, the BK employee hadn't removed the EXIF data from the uploaded photo, which suggested that the culprit was somewhere in Mayfield Heights, Ohio. This was at 11:47. 3 minutes later, at 11:50, the Burger King branch was posted with wishes of happy unemployment. 5 minutes later, the news station was contacted by another 4channer, and 3 minutes later at 11:58 a link was posted: BK's tell us about us online forum. The foot photo, otherwise known as Exhibit A, was attached. Cleveland Seen Magazine contacted the BK in question and the next day when questioned, the breakfast shift manager said "Oh, I know who that is, hes getting fired". Mystery solved, by 4chan. Now we can go back to eating our fast food in peace." + }, + "event_id": f"{os.urandom(16).hex()}:{server_name}", + "origin_server_ts": the_funny_number, + "room_id": roomId, + "sender": f"@vona:{server_name}", + "type": "m.room.message", + "unsigned": {} + }, + { + "content": { + "name": "Vona" + }, + "event_id": f"{os.urandom(16).hex()}:{server_name}", + "origin_server_ts": the_funny_number, + "room_id": roomId, + "sender": f"@vona:{server_name}", + "state_key": "", + "type": "m.room.name", + "unsigned": {} + } + ], + "end": f"{os.urandom(16).hex()}", + "start": f"{os.urandom(16).hex()}" + }) + +@client.route('/_matrix/client/v3/rooms//leave', methods=['POST']) +def leave_room(roomId): + return jsonify({}) + +@client.route('/_matrix/client/v3/rooms//read_markers', methods=['POST']) +def read_markers(roomId): + return jsonify({}) + +@client.route('/_matrix/client/v3/user//account_data/', methods=['PUT']) +async def set_custom_account_data(user, type): + return jsonify({}) + +@client.route('/_matrix/client/v3/keys/device_signing/upload', methods=['POST']) +async def upload_device_signing_keys(): + return jsonify({}) + +@client.route('/_matrix/client/v3/keys/query', methods=['POST']) +async def query_keys(): + # Should be replaced with + # something proper eventually. + return jsonify({}) diff --git a/src/config-example.py b/src/config-example.py new file mode 100644 index 0000000..c63f221 --- /dev/null +++ b/src/config-example.py @@ -0,0 +1,57 @@ +# Cat picture to use. Must be a JPEG (most camera photos are JPEG already anyway). +cat = '../cat.jpg' + +# Your server name. +server_name = "example.org" + +# Room directory room/space. +room_dir_room = { + "chunk": [ + { + "avatar_url": f"mxc://{server_name}/T2RoTUs3QyZUeT4kOC9NVzs4b", + "guest_can_join": False, + "join_rule": "public", + "name": "A [matrix] space", + "num_joined_members": 43502, + "room_id": f"!QDckPFoubl1NS2leKkpk:{server_name}", + "room_type": "m.space", + "topic": "A [matrix] space topic", + "world_readable": False + } + ], + "total_room_count_estimate": 43502 +} + +# Where users should reach out for support. +support = { + "contacts": [ + { + "email_address": "admin@i-didnt-change-my-vona-config.invalid", + "matrix_id": "@admin:i-didnt-change-my-vona-config.invalid", + "role": "m.role.admin" + }, + { + "email_address": "admin@i-didnt-change-my-vona-config.invalid", + "role": "m.role.security" + } + ] +} + +# The port to listen on. +port = 5000 + +# The address to listen on. +addr = '127.0.0.1' + +# Whether or not to enable registration. +users_can_register = False + +# The funny number. +the_funny_number = 1337 + +# Your private key for Vona. +# +# To generate a private key: +# openssl genpkey -algorithm Ed25519 -out privkey.pem +# +ed25519_key_path = "/etc/vonakey.pem" diff --git a/src/custom.py b/src/custom.py new file mode 100644 index 0000000..99fa490 --- /dev/null +++ b/src/custom.py @@ -0,0 +1,310 @@ +from config import server_name, the_funny_number, room_dir_room +from flask import Blueprint, jsonify, request, Response +from globals import vona_version, make_event_id +import base64 +import re +import os + +custom = Blueprint('matrix_custom', __name__) + +# This implements custom endpoints +# used by other homeserver +# implementations. They do not start +# with /_matrix/ + +# This should be split into more +# files eventually. + + +# Synapse +@custom.route('/_synapse/admin/v1/server_version') +def synapse_version(): + return jsonify({'server_version': vona_version}) + +@custom.route('/_synapse/admin/v2/users') +def synapse_user_list(): + return jsonify({ + "users": [ + { + "name": f"@vona:{server_name}", + "is_guest": 0, + "admin": 0, + "user_type": "vona", + "deactivated": 0, + "erased": False, + "shadow_banned": 0, + "displayname": "Vona", + "avatar_url": f"mxc://{server_name}/cat", + "creation_ts": the_funny_number, + "locked": False + } + ], + "total": 1 + }) + +@custom.route('/_synapse/admin/v2/users/', methods=['GET', 'PUT']) +def synapse_user_info(user_id): + if request.method == 'GET': + return jsonify({"name":f"@vona:{server_name}","displayname":"Vona","threepids":[],"avatar_url":f"mxc://{server_name}/cat","is_guest":0,"admin":0,"deactivated":0,"erased":False,"shadow_banned":0,"creation_ts":the_funny_number,"last_seen_ts":the_funny_number,"appservice_id":the_funny_number,"consent_server_notice_sent":the_funny_number,"consent_version":the_funny_number,"consent_ts":the_funny_number,"external_ids":[],"user_type":"vona","locked":False,"suspended":False}) + elif request.method == 'PUT': + return jsonify({}), 201 + +@custom.route('/_synapse/admin/v1/whois/') +def synapse_whois(user_id): + return jsonify({"user_id":f"@vona:{server_name}","devices":{"":{"sessions":[{"connections":[{"ip":f"{the_funny_number}.{the_funny_number}.{the_funny_number}.{the_funny_number}","last_seen":the_funny_number,"user_agent":f"Vona/{vona_version}"},{"ip":f"{the_funny_number}.{the_funny_number}.{the_funny_number}.{the_funny_number}","last_seen":the_funny_number,"user_agent":f"Vona/{vona_version}"}]}]}}}) + +@custom.route('/_synapse/admin/v1/deactivate/', methods=['POST']) +def synapse_deactivate(user_id): + return jsonify({}) + +@custom.route('/_synapse/admin/v1/suspend/', methods=['PUT']) +def synapse_suspend(user_id): + return jsonify({}) + +@custom.route('/_synapse/admin/v1/reset_password/', methods=['POST']) +def synapse_reset_pswd(user_id): + return jsonify({}) + +@custom.route('/_synapse/admin/v1/users//admin', methods=['PUT']) +def synapse_change_admin(user_id): + return jsonify({}) + +@custom.route('/_synapse/admin/v1/users//joined_rooms') +def synapse_user_joined_rooms(user_id): + return jsonify({"joined_rooms":[room_dir_room['chunk'][0]['room_id']],"total":1}) + +@custom.route('/_synapse/admin/v1/users//sent_invite_count') +def synapse_invite_count(user_id): + return jsonify({"invite_count": the_funny_number}) + +@custom.route('/_synapse/admin/v1/users//accountdata') +def synapse_account_data(user_id): + return jsonify({"account_data":{"global":{}}}) + +@custom.route('/_synapse/admin/v1/users//media', methods=['GET', 'DELETE']) +def synapse_account_media(user_id): + if request.method == 'GET': + return jsonify({"media": [{"created_ts":the_funny_number,"last_access_ts":the_funny_number,"media_id":"cat","media_length":the_funny_number,"media_type":"image/jpeg","quarantined_by":"null","safe_from_quarantine":False,"upload_name":"cat.jpg"}], "total": the_funny_number}) + elif request.method == 'DELETE': + return jsonify({"deleted_media": ["cat"], "total": the_funny_number}) + +@custom.route('/_synapse/admin/v1/users//login', methods=['POST']) +def synapse_account_login(user_id): + return jsonify({"access_token": "vona"}) + +@custom.route('/_synapse/admin/v1/users//_allow_cross_signing_replacement_without_uia', methods=['POST']) +def synapse_stupid_mas_bullshit(user_id): + return jsonify({"updatable_without_uia_before_ms": the_funny_number}) + +@custom.route('/_synapse/admin/v2/users//devices', methods=['GET', 'POST']) +def synapse_device_list(user_id): + if request.method == 'GET': + return jsonify({"devices":[{"device_id":"VVOONNAA","display_name":"Vona","last_seen_ip":"127.0.0.1","last_seen_ts":the_funny_number, "last_seen_user_agent": f"Vona/{vona_version}"}], "total": the_funny_number}) + elif request.method == 'POST': + return jsonify({}) + +@custom.route('/_synapse/admin/v2/users//delete_devices', methods=['POST']) +def synapse_delete_devices(user_id): + return jsonify({}) + +@custom.route('/_synapse/admin/v2/users//devices/') +def synapse_device_info(user_id, device_id): + if request.method == 'GET': + return jsonify({"device_id":"VVOONNAA","display_name":"Vona","last_seen_ip":"127.0.0.1","last_seen_ts":the_funny_number, "last_seen_user_agent": f"Vona/{vona_version}"}) + else: + return jsonify({}) + +@custom.route('/_synapse/admin/v1/users//pushers') +def synapse_pushers(user_id): + return jsonify({"pushers": [], "total": the_funny_number}) + +@custom.route('/_synapse/admin/v1/users//shadow_ban', methods=['DELETE', 'POST']) +def synapse_shadow_ban(user_id): + return jsonify({}) + +@custom.route('/_synapse/admin/v1/users//override_ratelimit', methods=['GET', 'POST', 'DELETE']) +def synapse_override_ratelimit(user_id): + return jsonify({}) + +@custom.route('/_synapse/admin/v1/username_available') +def synapse_username_available(): + return jsonify({"available": True}) + +@custom.route('/_synapse/admin/v1/auth_providers//users/') +def synapse_auth_providers(provider, ext): + return jsonify({"user_id": f"@vona:{server_name}"}) + +@custom.route('/_synapse/admin/v1/threepid//users/') +def synapse_threepid(medium, addr): + return jsonify({"user_id": f"@vona:{server_name}"}) + +@custom.route('/_synapse/admin/v1//redact') +def synapse_redact(user_id): + return jsonify({"redact_id": os.urandom(16).hex()}) + +@custom.route('/_synapse/admin/v1/user/redact_status/') +def synapse_redact_status(redact_id): + return jsonify({"status":"active","failed_redactions":[]}) + +@custom.route('/_synapse/admin/v1/experimental_features/', methods=['GET', 'PUT']) +def synapse_experimental_features(user_id): + return jsonify({"features": {}}) + +@custom.route('/_synapse/admin/v1/register', methods=['GET', 'POST']) +def synapse_register(): + if request.method == 'GET': + return jsonify({"nonce": os.urandom(16).hex()}) + elif request.method == 'POST': + return jsonify({"access_token": f"@vona:{server_name}"}) + +@custom.route('/_synapse/admin/v1/join/', methods=['POST']) +def synapse_membership_manipulation(roomId): + return jsonify({"room_id": room_dir_room['chunk'][0]['room_id']}) + +@custom.route('/_synapse/admin/v1/account_validity/validity', methods=['POST']) +def synapse_account_validity(): + return jsonify({"expiration_ts": the_funny_number}) + +@custom.route('/_synapse/admin/v1/send_server_notice', methods=['POST']) +def synapse_server_notice(): + return jsonify({"event_id": make_event_id()}) + +@custom.route('/_synapse/admin/v1/send_server_notice/', methods=['PUT']) +def synapse_server_notice_second(txnId): + return jsonify({"event_id": make_event_id()}) + +@custom.route('/_synapse/admin/v1/purge_history/', methods=['POST']) +def synapse_purge_room_history(room_id): + return jsonify({"purge_id": os.urandom(16).hex()}) + +@custom.route('/_synapse/admin/v1/purge_history//', methods=['POST']) +def synapse_purge_event(room_id, event_id): + return jsonify({"purge_id": os.urandom(16).hex()}) + +@custom.route('/_synapse/admin/v1/purge_history_status/') +def synapse_purge_status(purge_id): + return jsonify({"status":"active"}) + +@custom.route('/_synapse/admin/v1/room//media') +def synapse_room_media(room_id): + return jsonify({"local": [f"mxc://{server_name}/cat"], "remote": []}) + +@custom.route('/_synapse/admin/v1/media/quarantine//', methods=['POST']) +def synapse_quarantine_media(server_name, media_id): + return jsonify({}) + +@custom.route('/_synapse/admin/v1/media/unquarantine//', methods=['POST']) +def synapse_unquarantine_media(server_name, media_id): + return jsonify({}) + +@custom.route('/_synapse/admin/v1/room//media/quarantine', methods=['POST']) +def synapse_quarantine_room_media(room_id): + return jsonify({"num_quarantined": the_funny_number}) + +@custom.route('/_synapse/admin/v1/media/protect/', methods=['POST']) +def synapse_protect_media(media_id): + return jsonify({}) + +@custom.route('/_synapse/admin/v1/media/unprotect/', methods=['POST']) +def synapse_unprotect_media(media_id): + return jsonify({}) + +@custom.route('/_synapse/admin/v1/media//', methods=['DELETE']) +def synapse_delete_single_media(media_id): + return jsonify({"deleted_media": ["cat"], "total": the_funny_number}) + +@custom.route('/_synapse/admin/v1/media/delete', methods=['POST']) +def synapse_delete_media(): + return jsonify({"deleted_media": ["cat"], "total": the_funny_number}) + +@custom.route('/_synapse/admin/v1/media//delete', methods=['POST']) +def synapse_delete_media_from_server(server_name): + return jsonify({"deleted_media": ["cat"], "total": the_funny_number}) + +@custom.route('/_synapse/admin/v1/purge_media_cache', methods=['POST']) +def synapse_delete_remote_media(): + return jsonify({"deleted": the_funny_number}) + +@custom.route('/_synapse/admin/v1/statistics/users/media') +def synapse_media_stats(): + return jsonify({"users":[{"displayname":"Vona","media_count":the_funny_number,"media_length":the_funny_number,"user_id":f"@vona:{server_name}"}],"total":the_funny_number}) + +@custom.route('/_synapse/admin/v1/statistics/database/rooms') +def synapse_room_stats(): + return jsonify({"rooms": [{"room_id":room_dir_room['chunk'][0]['room_id'],"estimated_size":the_funny_number}]}) + +@custom.route('/_synapse/admin/v1/background_updates/status') +def synapse_background_upate_status(): + return jsonify({"enabled":False}) + +@custom.route('/_synapse/admin/v1/background_updates/enabled', methods=['POST', 'GET']) +def synapse_change_bg_update(): + return jsonify({"enabled":False}) + +# No documentation on what Synapse actually returns for this API, so a blank dict for now. +@custom.route('/_synapse/admin/v1/background_updates/start_job', methods=['POST']) +def synapse_bg_update_start_job(): + return jsonify({}) + +@custom.route('/_synapse/admin/v1/event_reports') +def synapse_event_reports(): + return jsonify({"event_reports": [{"event_id": f"${make_event_id()}","id": the_funny_number,"reason": "vona","score": the_funny_number,"received_ts": the_funny_number,"room_id": room_dir_room['chunk'][0]['room_id'],"name": room_dir_room['chunk'][0]['name'],"sender": f"@vona:{server_name}","user_id": f"@vona:{server_name}"}],"total": the_funny_number}) + +@custom.route('/_synapse/admin/v1/event_reports/', methods=['GET', 'DELETE']) +def synapse_interact_with_reported_event(report_id): + if request.method == 'GET': + return jsonify({"event_id": f"${make_event_id()}","event_json": {"auth_events": [],"content": {"msgtype": "m.text","body": "Number 15: Burger King Foot Lettuce.\nThe last thing you'd want in your Burger King burger is someones foot fungus, but as it turns out, that might be what you get. A 4channer uploaded a photo, anonymously to the site showcasing his feet in a plastic bin of lettuce with the statement \"This is the lettuce you eat at Burger King.\". Admittedly, he had shoes on, but thats even worse. The post went live at 11:38 PM on July 16 and a mere 20 minutes later the Burger King in question was alerted to the rogue employee. At least, I hope hes rogue. How did it happen? Well, the BK employee hadn't removed the EXIF data from the uploaded photo, which suggested that the culprit was somewhere in Mayfield Heights, Ohio. This was at 11:47. 3 minutes later, at 11:50, the Burger King branch was posted with wishes of happy unemployment. 5 minutes later, the news station was contacted by another 4channer, and 3 minutes later at 11:58 a link was posted: BK's tell us about us online forum. The foot photo, otherwise known as Exhibit A, was attached. Cleveland Seen Magazine contacted the BK in question and the next day when questioned, the breakfast shift manager said \"Oh, I know who that is, hes getting fired\". Mystery solved, by 4chan. Now we can go back to eating our fast food in peace.","format": "org.matrix.custom.html","formatted_body": "Number 15: Burger King Foot Lettuce.
The last thing you'd want in your Burger King burger is someones foot fungus, but as it turns out, that might be what you get. A 4channer uploaded a photo, anonymously to the site showcasing his feet in a plastic bin of lettuce with the statement "This is the lettuce you eat at Burger King.". Admittedly, he had shoes on, but thats even worse. The post went live at 11:38 PM on July 16 and a mere 20 minutes later the Burger King in question was alerted to the rogue employee. At least, I hope hes rogue. How did it happen? Well, the BK employee hadn't removed the EXIF data from the uploaded photo, which suggested that the culprit was somewhere in Mayfield Heights, Ohio. This was at 11:47. 3 minutes later, at 11:50, the Burger King branch was posted with wishes of happy unemployment. 5 minutes later, the news station was contacted by another 4channer, and 3 minutes later at 11:58 a link was posted: BK's tell us about us online forum. The foot photo, otherwise known as Exhibit A, was attached. Cleveland Seen Magazine contacted the BK in question and the next day when questioned, the breakfast shift manager said "Oh, I know who that is, hes getting fired". Mystery solved, by 4chan. Now we can go back to eating our fast food in peace."},"depth": the_funny_number,"hashes": {"sha256": f"${make_event_id()}"},"origin": server_name,"origin_server_ts": the_funny_number,"prev_events": [f"${make_event_id()}"],"prev_state": [],"room_id": room_dir_room['chunk'][0]['room_id'],"sender": f"@vona:{server_name}","signatures": {server_name: {"ed25519:a_JaEG": base64.b64encode(os.urandom(32)).decode('utf-8')[:87]}}},"type": "m.room.message","unsigned": {"age_ts": the_funny_number},"id": the_funny_number,"reason": "vona","score": the_funny_number,"received_ts": the_funny_number,"room_id": room_dir_room['chunk'][0]['room_id'],"name": room_dir_room['chunk'][0]['name'],"sender": f"@vona:{server_name}","user_id": f"@vona:{server_name}"}) + else: + return jsonify({}) + +# Dendrite - https://element-hq.github.io/dendrite/administration/adminapi +@custom.route('/_dendrite/admin/evacuateUser/', methods=['POST']) +def dendrite_evacuate_user(userId): + return jsonify({"affected":[room_dir_room['chunk'][0]['room_id']]}) + +@custom.route('/_dendrite/admin/evacuateRoom/', methods=['POST']) +def dendrite_evacuate_room(roomId): + return jsonify({"affected":[f"@vona:{server_name}"]}) + +@custom.route('/_dendrite/admin/resetPassword/', methods=['POST']) +def dendrite_reset_pswd(userId): + return jsonify({"password_updated":true}) + +@custom.route('/_dendrite/admin/purgeRoom/', methods=['POST']) +def dendrite_purge_room(roomId): + return jsonify({}) + +@custom.route('/_dendrite/admin/refreshDevices/', methods=['POST']) +def dendrite_refresh_devices(userId): + return jsonify({}) + +@custom.route('/_dendrite/admin/fulltext/reindex') +def dendrite_reindex(): + return jsonify({}) + +# Conduwuit +@custom.route('/_conduwuit/local_user_count') +def conduwuit_user_count(): + return jsonify({"count": the_funny_number}) + +@custom.route('/_conduwuit/server_version') +def conduwuit_server_version(): + return jsonify({"name":"Vona","version":vona_version}) + +# Continuwuity +@custom.route('/_continuwuity/local_user_count') +def continuwuity_user_count(): + return jsonify({"count": the_funny_number}) + +@custom.route('/_continuwuity/server_version') +def continuwuity_server_version(): + return jsonify({"name":"Vona","version":vona_version}) + +# Tuwunel +@custom.route('/_tuwunel/local_user_count') +def tuwunel_user_count(): + return jsonify({"count": the_funny_number}) + +@custom.route('/_tuwunel/server_version') +def tuwunel_server_version(): + return jsonify({"name":"Vona","version":vona_version}) diff --git a/src/globals.py b/src/globals.py new file mode 100644 index 0000000..a5bbd93 --- /dev/null +++ b/src/globals.py @@ -0,0 +1,50 @@ +from cryptography.hazmat.backends import default_backend +from cryptography.hazmat.primitives import serialization +import hashlib +import base64 +import json +import re +import os + +def canonical_json(value): + return json.dumps( + value, + ensure_ascii=False, + separators=(',',':'), + sort_keys=True + ).encode("UTF-8") + +''' +def encode_base64(data: bytes) -> str: + return base64.b64encode(data).decode('utf-8') + +def sign_json(json_object, signing_key, signing_name): + signatures = json_object.pop("signatures", {}) + unsigned = json_object.pop("unsigned", None) + + signed = signing_key.sign(canonical_json(json_object)) + signature_base64 = encode_base64(signed) + + key_id = "ed25519:VonaA" + signatures.setdefault(signing_name, {})[key_id] = signature_base64 + + json_object["signatures"] = signatures + if unsigned is not None: + json_object["unsigned"] = unsigned + + return json_object +''' + +vona_version = '1.2.3' + +def make_event_id(): + return re.sub(r'[\/+=]', '_', base64.b64encode(os.urandom(32)).decode('utf-8'))[:44] + +def hash_event(input) -> str: + input.pop('signatures', None) + input.pop('unsigned', None) + + sha256_hash = hashlib.sha256(canonical_json(input)).digest() + base64_encoded = base64.b64encode(sha256_hash) + + return base64_encoded.decode().rstrip('=') diff --git a/src/identity.py b/src/identity.py new file mode 100644 index 0000000..5b0b5df --- /dev/null +++ b/src/identity.py @@ -0,0 +1,122 @@ +from flask import Blueprint, jsonify, request +from config import server_name, the_funny_number + +identity = Blueprint("matrix_identity", __name__) + +# This implements being an identity server. +# I'm pretty sure only Element uses this, +# but oh well. + +# https://spec.matrix.org/v1.15/identity-service-api/#api-version-check +@identity.route("/_matrix/identity/versions") +async def versions(): + return jsonify({"versions":["r0.1.0","r0.2.0","r0.2.1","r0.3.0","v1.1","v1.2","v1.3","v1.4","v1.5"]}) + + +# https://spec.matrix.org/v1.15/identity-service-api/#authentication +@identity.route("/_matrix/identity/v2/account") +async def account_info(): + return jsonify({"user_id": f"@vona:{server_name}"}) + +@identity.route("/_matrix/identity/v2/account/logout", methods=['POST']) +async def logout(): + return jsonify({}) + +@identity.route("/_matrix/identity/v2/account/register", methods=['POST']) +async def register(): + return jsonify({"token":"vona"}) + + +# https://spec.matrix.org/v1.15/identity-service-api/#terms-of-service +@identity.route('/_matrix/identity/v2/terms', methods=['GET', 'POST']) +async def policies(): + if request.method == 'GET': + return jsonify({"policies":{}}) + + return jsonify({}) + + +# https://spec.matrix.org/v1.15/identity-service-api/#status-check +@identity.route('/_matrix/identity/v2') +async def status(): + return jsonify({}) + + +# https://spec.matrix.org/v1.15/identity-service-api/#key-management +@identity.route('/_matrix/identity/v2/pubkey/ephemeral/isvalid') +async def pubkey_eph_validity(): + return jsonify({"valid":True}) + +@identity.route('/_matrix/identity/v2/pubkey/isvalid') +async def pubkey_validity(): + return jsonify({"valid":True}) + +@identity.route('/_matrix/identity/v2/pubkey/') +async def get_key(key): + return jsonify({"errcode":"M_NOT_FOUND","error":"The public key was not found"}), 404 + + +# https://spec.matrix.org/v1.15/identity-service-api/#association-lookup +@identity.route('/_matrix/identity/v2/hash_details') +async def hash_details(): + return jsonify({"algorithms":["none","sha256"],"lookup_pepper": "vona"}) + +@identity.route('/_matrix/identity/v2/lookup', methods=['POST']) +async def lookup(): + req = request.json + + if 'addresses' in req: + return jsonify({"mappings": {req['addresses'][0]: f"@vona:{server_name}"}}) + else: + return jsonify({"errcode": "M_INVALID_PEPPER","error": "Invalid pepper"}) + + +# https://spec.matrix.org/v1.15/identity-service-api/#establishing-associations +@identity.route('/_matrix/identity/v2/validate/email/requestToken', methods=['POST']) +async def request_email_token(): + return jsonify({"sid":str(the_funny_number)}) + +@identity.route('/_matrix/identity/v2/validate/email/submitToken', methods=['GET', 'POST']) +async def submit_email_token(): + return jsonify({"success":True}) + +@identity.route('/_matrix/identity/v2/validate/msisdn/requestToken', methods=['POST']) +async def request_phone_token(): + return jsonify({"sid":str(the_funny_number)}) + +@identity.route('/_matrix/identity/v2/validate/msisdn/submitToken', methods=['GET', 'POST']) +async def submit_phone_token(): + return jsonify({"success":True}) + +@identity.route('/_matrix/identity/v2/3pid/bind', methods=['POST']) +async def threepid_bind(): + # We have to do signature stuff here, + # this will be implemented properly + # when I actually get sigs working. + + return jsonify({}) + +@identity.route('/_matrix/identity/v2/3pid/unbind', methods=['POST']) +async def threepid_unbind(): + return jsonify({}) + +@identity.route('/_matrix/identity/v2/3pid/getValidated3pid') +async def threepid_validated(): + # Please email abuse@matrix.org + + return jsonify({"address":"abuse@matrix.org","medium":"email","validated_at":the_funny_number}) + + +# https://spec.matrix.org/v1.15/identity-service-api/#invitation-storage +@identity.route('/_matrix/identity/v2/store-invite', methods=['POST']) +async def invite(): + return jsonify({"display_name":"Vona","public_keys":[{"key_validity_url":"https://example.com/_matrix/identity/v2/pubkey/isvalid","public_key":"ohyeah"},{"key_validity_url":"https://example.com/_matrix/identity/v2/pubkey/ephemeral/isvalid","public_key":"thisssssss"}],"token":"vona"}) + + +# https://spec.matrix.org/v1.15/identity-service-api/#ephemeral-invitation-signing +@identity.route('/_matrix/identity/v2/sign-ed25519', methods=['POST']) +async def invite_signing(): + # the spec sez this is insecure :trole: + return jsonify({ + "errcode":"M_TERMS_NOT_SIGNED","error":"Please accept our updated terms of service before continuing" + }), 403 diff --git a/src/main.py b/src/main.py new file mode 100644 index 0000000..7a32657 --- /dev/null +++ b/src/main.py @@ -0,0 +1,70 @@ +from flask import Flask, jsonify, request, redirect +import globals +import config + +from identity import identity +from appservice import apps +from custom import custom +from policy import policy +from c2s import client +from s2s import server + +app = Flask(__name__) + +app.register_blueprint(identity) +app.register_blueprint(policy) +app.register_blueprint(client) +app.register_blueprint(custom) +app.register_blueprint(server) +app.register_blueprint(apps) + + +# Landing page +@app.route("/") +async def root(): + return redirect("/_matrix/static/", 308) + +@app.route("/_matrix/static/") +async def matrix_static(): + return f'Vona {globals.vona_version} is running

It works! Vona {globals.vona_version} is running

Your Vona server is listening on this port and is ready for messages.

Welcome to the Matrix universe :)


matrix.org

' + + +# Error handlers +@app.errorhandler(404) +async def not_found(error): + return jsonify({"errcode": "M_UNRECOGNIZED", "error": "Unrecognized request"}), 404 + +@app.errorhandler(405) +async def invalid_request_method(error): + return jsonify({"errcode": "M_UNRECOGNIZED", "error": "Unrecognized request"}), 405 + +@app.errorhandler(500) +async def internal_error(error): + return jsonify({"errcode": "M_UNKNOWN", "error": "Internal server error"}), 500 + + +# Well-known endpoints for federation, +# clients, and support information +@app.route("/.well-known/matrix/server") +async def server(): + return jsonify({"m.server": f"{config.server_name}:443"}) + +@app.route("/.well-known/matrix/support") +async def support(): + if config.support: + return jsonify(config.support) + else: + abort(404) + +@app.route("/.well-known/matrix/client") +async def client(): + return jsonify({ + "m.homeserver": {"base_url": f"https://{config.server_name}"}, + "m.identity_server": {"base_url": f"https://{config.server_name}"}, + }) + + +if __name__ == "__main__": + app.run(host=config.addr, port=config.port) +else: + print("What the hell are you doing?") diff --git a/src/policy.py b/src/policy.py new file mode 100644 index 0000000..2be1b9e --- /dev/null +++ b/src/policy.py @@ -0,0 +1,29 @@ +from flask import jsonify, Blueprint, request + +policy = Blueprint("policy_server", __name__) + +matrix_org = [ + "dendrite.matrix.org", + "matrix.org", + "element.io", + "t2l.io", + "t2bot.io" +] + + +@policy.route("/_matrix/policy/v1/event//check", methods=["POST"]) +def check_event(eventId): + if request.get_json()["origin"] in matrix_org: + return jsonify({"recommendation": "spam"}) + else: + return jsonify({"recommendation": "ok"}) + +@policy.route( + "/_matrix/policy/unstable/org.matrix.msc4284/event//check", + methods=["POST"], +) +def check_event_unstable(eventId): + if request.get_json()["origin"] in matrix_org: + return jsonify({"recommendation": "spam"}) + else: + return jsonify({"recommendation": "ok"}) diff --git a/src/s2s.py b/src/s2s.py new file mode 100644 index 0000000..5ff0a80 --- /dev/null +++ b/src/s2s.py @@ -0,0 +1,245 @@ +from flask import Flask, jsonify, Response, request, send_file, abort, Blueprint +from globals import vona_version, make_event_id, hash_event +from config import * +import requests +import json +import os + +server = Blueprint('matrix_server', __name__) + +def send_join(request, roomId): + # We may have to include signatures here + # as well, which will be a pain + + eventIds = [ + f"${make_event_id()}:{server_name}", + f"${make_event_id()}:{server_name}", + f"${make_event_id()}:{server_name}", + f"${make_event_id()}:{server_name}" + ] + + events = { + "auth_chain": [eventIds[2], eventIds[3]], + "event": {}, + "members_omitted": True, + "servers_in_room": [server_name], + "state": [ + { + "content": { + "room_version": the_funny_number, + "creator": f"@vona:{server_name}" + }, + "room_id": roomId, + "event_id": eventIds[0], + "state_key": "", + "origin_server_ts": 1, + "type": "m.room.create", + "sender": f"@vona:{server_name}" + }, + { + "content": {"membership": "join"}, + "room_id": roomId, + "event_id": eventIds[1], + "state_key": f"@vona:{server_name}", + "origin_server_ts": 2, + "type": "m.room.member", + "sender": f"@vona:{server_name}" + }, + { + "content": {"users": {f"@vona:{server_name}": 100}}, + "room_id": roomId, + "event_id": eventIds[2], + "state_key": "", + "origin_server_ts": 3, + "type": "m.room.power_levels", + "sender": f"@vona:{server_name}" + }, + { + "content": {"join_rule": "public"}, + "room_id": roomId, + "event_id": eventIds[3], + "state_key": "", + "origin_server_ts": 4, + "type": "m.room.join_rules", + "sender": f"@vona:{server_name}" + } + ] + } + + for event in events['state']: + event_hash = hash_event(event) + if event['type'] != "m.room.create": + event['prev_events'] = [eventIds[event['origin_server_ts'] - 1], {"sha256": event_hash}] + + join_event = request.json + join_event['prev_events'] = [eventIds[3], {"sha256": events['state'][3]['prev_events'][1]['sha256']}] + events['event'] = join_event + + print(json.dumps(events, indent='\t')) + print(json.dumps(eventIds, indent='\t')) + + return events + +@server.route('/_matrix/federation/v1/version') +def version(): + return jsonify({"server": {"version": vona_version,"name": "Vona"}}) + +@server.route('/_matrix/key/v2/server') +def keys(): + # todo + return jsonify({}) + +@server.route('/_matrix/federation/v1/query/directory') +def room_query(): + return jsonify({ + "room_id": room_dir_room['chunk'][0]['room_id'], + "servers": [server_name] + }) + +@server.route('/_matrix/federation/v1/media/download/') +def download_media(media_id): + # Auth media requires this to be + # multipart despite not even using + # it for anything. Minor annoyance. + + with open(cat, 'rb') as img_file: + image_data = img_file.read() + boundary = '----WebKitFormBoundary7MA4YWxkTrZu0gW' + response_body = ( + f'--{boundary}\r\n' + f'Content-Type: application/json\r\n\r\n' + f'{{}}\r\n' + f'--{boundary}\r\n' + f'Content-Type: image/jpeg\r\n' + f'Content-Disposition: attachment; filename="cat.jpg"\r\n\r\n' + ).encode() + image_data + f'\r\n--{boundary}--\r\n'.encode() + + response = Response(response_body, content_type=f'multipart/mixed; boundary={boundary}') + response.status_code = 200 + return response + +@server.route('/_matrix/federation/v1/media/thumbnail/') +def thumbnail_media(media_id): + return jsonify({"errcode": "M_TOO_CUTE","error": "Cat is too cute to thumbnail"}), 403 + +@server.route('/_matrix/federation/v1/send_join//', methods=['PUT']) +def send_join_v1(roomId, eventId): + return jsonify(send_join(request, roomId)) + +@server.route('/_matrix/federation/v2/send_join//', methods=['PUT']) +def send_join_v2(roomId, eventId): + return jsonify(send_join(request, roomId)) + +@server.route('/_matrix/federation/v1/make_join//') +def make_join(roomId, userId): + return jsonify({ + "event": { + "content": { + "join_authorised_via_users_server": f"@vona:{server_name}", + "membership": "join" + }, + "origin": server_name, + "origin_server_ts": str(the_funny_number), + "room_id": roomId, + "sender": userId, + "state_key": userId, + "type": "m.room.member" + }, + "room_version": "2" + }) + +@server.route('/_matrix/federation/v1/publicRooms', methods=['POST', 'GET']) +def room_directory(): + return jsonify(room_dir_room) + + +# https://spec.matrix.org/v1.15/server-server-api/#transactions +@server.route('/_matrix/federation/v1/send/', methods=['PUT']) +def federation_send(txnId): + # This only works for v2 rooms, but anything + # bigger than v2 isn't real, so not a problem + + data = request.data.decode('utf-8') + parsed_data = json.loads(data) + response = {"pdus": {}} + + if 'pdus' in parsed_data and parsed_data['pdus']: + for pdu in parsed_data['pdus']: + if 'hashes' in pdu and 'sha256' in pdu['hashes']: + pdu_hash = pdu['hashes']['sha256'] + response_key = f"${pdu_hash}:{parsed_data['origin']}" + response["pdus"][response_key] = {} + + return jsonify(response) + +@server.route('/_matrix/federation/v1/query/profile') +def user_profile(): + field = request.args.get('field') + if field: + if field == 'avatar_url': + return jsonify({"avatar_url":f"mxc://{server_name}/cat"}) + elif field == 'displayname': + return jsonify({"displayname":"Vona"}) + else: + return jsonify({"errcode": "M_NOT_FOUND","error": "The requested profile key does not exist."}), 404 + return jsonify({"avatar_url": f"mxc://{server_name}/cat","displayname": "Vona"}) + +@server.route('/_matrix/federation/v1/user/devices/') +def user_devices(user): + return jsonify({ + "devices": [], + "stream_id": the_funny_number, + "user_id": f"@vona:{server_name}" +}) + +@server.route('/_matrix/federation/v1/user/keys/query', methods=['POST']) +def user_keys(): + return jsonify({"device_keys":{f"@vona:{server_name}":{}}}) + +@server.route('/_matrix/federation/v2/invite//', methods=['PUT']) +def fed_invite_user(room, txnId): + return jsonify({"errcode":"M_INCOMPATIBLE_ROOM_VERSION","error": "Don't touch my users mofo","room_version": str(the_funny_number)}), 400 + +@server.route('/_matrix/federation/v1/hierarchy/') +def space_hierachy(roomId): + room = room_dir_room['chunk'][0] + return jsonify({ + "children": [{ + "avatar_url": room['avatar_url'], + "children_state": [{ + "content": {"via": [server_name]}, + "origin_server_ts": the_funny_number, + "sender": f"@vona:{server_name}", + "state_key": room['room_id'], + "type": "m.space.child" + }], + "guest_can_join": room['guest_can_join'], + "join_rule": room['join_rule'], + "name": room['name'], + "num_joined_members": room['num_joined_members'], + "room_id": room['room_id'], + "room_type": room['room_type'], + "topic": room['topic'], + "world_readable": room['world_readable'] + }], + "inaccessible_children": [], + "room": { + "allowed_room_ids": [], + "avatar_url": room['avatar_url'], + "children_state": [{ + "content": {"via": [server_name]}, + "origin_server_ts": the_funny_number, + "sender": f"@vona:{server_name}", + "state_key": room['room_id'], + "type": "m.space.child" + }], + "guest_can_join": room['guest_can_join'], + "join_rule": room['join_rule'], + "name": room['name'], + "num_joined_members": room['num_joined_members'], + "room_id": room['room_id'], + "room_type": room['room_type'], + "topic": room['topic'], + "world_readable": room['world_readable'] + } + })

To use this server you\'ll need a Matrix client.