From 0e6518915d038f1845bfb866adeda83ca55f1e53 Mon Sep 17 00:00:00 2001 From: Jakob Ketterl Date: Sat, 4 Jul 2020 21:47:56 +0200 Subject: [PATCH] * refactor receiverid into a separate controller base * allow multiple headers to prepare for checking multiple claims --- owrx/controllers/__init__.py | 6 +++++- owrx/controllers/receiverid.py | 21 +++++++++++++++++++++ owrx/controllers/status.py | 13 +++---------- owrx/receiverid.py | 21 ++++++++++++++------- 4 files changed, 43 insertions(+), 18 deletions(-) create mode 100644 owrx/controllers/receiverid.py diff --git a/owrx/controllers/__init__.py b/owrx/controllers/__init__.py index c00eebd..6839741 100644 --- a/owrx/controllers/__init__.py +++ b/owrx/controllers/__init__.py @@ -18,7 +18,11 @@ class Controller(object): if max_age is not None: headers["Cache-Control"] = "max-age: {0}".format(max_age) for key, value in headers.items(): - self.handler.send_header(key, value) + if isinstance(value, list): + for v in value: + self.handler.send_header(key, v) + else: + self.handler.send_header(key, value) self.handler.end_headers() if type(content) == str: content = content.encode() diff --git a/owrx/controllers/receiverid.py b/owrx/controllers/receiverid.py new file mode 100644 index 0000000..6489340 --- /dev/null +++ b/owrx/controllers/receiverid.py @@ -0,0 +1,21 @@ +from owrx.controllers import Controller +from owrx.receiverid import ReceiverId +from datetime import datetime + + +class ReceiverIdController(Controller): + def __init__(self, handler, request, options): + super().__init__(handler, request, options) + self.authHeaders = [] + + def send_response(self, content, code=200, content_type="text/html", last_modified: datetime = None, max_age=None, headers=None): + if headers is None: + headers = {} + headers['Authorization'] = self.authHeaders + super().send_response(content, code=code, content_type=content_type, last_modified=last_modified, max_age=max_age, headers=headers) + pass + + def handle_request(self): + headers = self.request.headers.get_all("Authorization", []) + self.authHeaders = [ReceiverId.getResponseHeader(h) for h in headers] + super().handle_request() diff --git a/owrx/controllers/status.py b/owrx/controllers/status.py index c3100de..9e6a820 100644 --- a/owrx/controllers/status.py +++ b/owrx/controllers/status.py @@ -1,8 +1,7 @@ -from . import Controller +from .receiverid import ReceiverIdController from owrx.version import openwebrx_version from owrx.sdr import SdrService from owrx.config import Config -from owrx.receiverid import ReceiverId, KeyException import json import logging @@ -10,7 +9,7 @@ import logging logger = logging.getLogger(__name__) -class StatusController(Controller): +class StatusController(ReceiverIdController): def getProfileStats(self, profile): return { "name": profile["name"], @@ -29,12 +28,6 @@ class StatusController(Controller): def indexAction(self): pm = Config.get() - headers = None - if "Authorization" in self.request.headers: - try: - headers = ReceiverId.getResponseHeader(self.request.headers["Authorization"]) - except KeyException: - logger.exception("error processing authorization header") status = { "receiver": { "name": pm["receiver_name"], @@ -47,4 +40,4 @@ class StatusController(Controller): "version": openwebrx_version, "sdrs": [self.getReceiverStats(r) for r in SdrService.getSources().values()] } - self.send_response(json.dumps(status), content_type="application/json", headers=headers) + self.send_response(json.dumps(status), content_type="application/json") diff --git a/owrx/receiverid.py b/owrx/receiverid.py index bae2728..33c62f0 100644 --- a/owrx/receiverid.py +++ b/owrx/receiverid.py @@ -38,8 +38,19 @@ class KeyChallenge(object): class KeyResponse(object): + def __init__(self, source, id, time: datetime, signature): + self.source = source + self.id = id + self.time = time + self.signature = signature + def __str__(self): - return "TODO" + return "Time={time}, Response={source}-{id}-{signature}".format( + source=self.source, + id=self.id, + signature=self.signature, + time=self.time + ) class ReceiverId(object): @@ -52,11 +63,7 @@ class ReceiverId(object): key = ReceiverId.findKey(challenge) if key is None: return {} - time, signature = ReceiverId.signChallenge(challenge, key) - return { - "Signature": signature, - "Time": time, - } + return ReceiverId.signChallenge(challenge, key) @staticmethod def findKey(challenge): @@ -78,4 +85,4 @@ class ReceiverId(object): m = hmac.new(bytes.fromhex(key.secret), digestmod=hashlib.sha256) m.update(bytes.fromhex(challenge.challenge)) m.update(now.encode('utf8')) - return now, m.hexdigest() + return KeyResponse(challenge.source, challenge.id, now, m.hexdigest())