# Python 3.11.2 (main, May 12 2026, 05:17:27) [GCC 12.2.0] on linux # bottle 0.12.23 # Copyright (C) 2022 Noisytoot # 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 . import json import configparser import hmac import hashlib import base64 import time import sys import bottle from bottle import run, abort, default_app, get, post, request, response config = configparser.ConfigParser() config.read('coldwetsasl.conf') bind_host = config['bind'].get('host', 'localhost') bind_port = config['bind'].get('port', 8080) hmac_secret = config['hmac']['secret'].encode() def commentify(string): return '\n'.join(['# ' + line for line in string.split('\n')]) source_str = commentify(f"""\ Python {sys.version} on {sys.platform} bottle {bottle.__version__}""") + '\n\n' with open(__file__) as source_file: source_str += source_file.read() def get_hmac(msg): return base64.b64encode( hmac.new( hmac_secret, msg=msg, digestmod=hashlib.sha256 ).digest()).decode() @get('/') def source(): response.content_type = 'text/plain; charset=utf-8' return source_str @post('/') def sasl(): body = request.body.read() request_hmac = request.headers.get('X-HMAC') print(request_hmac, get_hmac(body)) if request_hmac is None or not hmac.compare_digest(request_hmac, get_hmac(body)): abort(401, 'Invalid HMAC') try: data = json.loads(body) except json.decoder.JSONDecodeError: abort(400, 'Invalid JSON') if not data.get('reqExpires', None) or int(data['reqExpires']) < int(time.time()): abort(401, 'Request expired') if data['data']['user'] == 'localhost@piss' and data['misc']['ip'] == '127.0.0.1': return { 'fail': False, 'success': True, 'account': 'PISS-LOCALHOST' } else: return { 'fail': False, 'success': False } if __name__ == "__main__": run(host=bind_host, port=bind_port) else: app = application = default_app()