receiver receiverid challenge and find corresponding key

This commit is contained in:
Jakob Ketterl 2020-06-10 20:09:40 +02:00
parent c0f447ca20
commit 61d03b38b9
3 changed files with 85 additions and 14 deletions

View File

@ -1,11 +1,13 @@
from . import Controller from . import Controller
from owrx.client import ClientRegistry
from owrx.version import openwebrx_version from owrx.version import openwebrx_version
from owrx.sdr import SdrService from owrx.sdr import SdrService
from owrx.config import Config from owrx.config import Config
import os from owrx.receiverid import ReceiverId, KeyException
import json import json
import pkg_resources
import logging
logger = logging.getLogger(__name__)
class StatusController(Controller): class StatusController(Controller):
@ -27,7 +29,11 @@ class StatusController(Controller):
def indexAction(self): def indexAction(self):
pm = Config.get() pm = Config.get()
if "Authorization" in self.request.headers:
try:
ReceiverId.getResponseHeader(self.request.headers["Authorization"])
except KeyException:
logger.exception("error processing authorization header")
status = { status = {
"receiver": { "receiver": {
"name": pm["receiver_name"], "name": pm["receiver_name"],

View File

@ -35,19 +35,26 @@ class RequestHandler(BaseHTTPRequestHandler):
logger.debug("%s - - [%s] %s", self.address_string(), self.log_date_time_string(), format % args) logger.debug("%s - - [%s] %s", self.address_string(), self.log_date_time_string(), format % args)
def do_GET(self): def do_GET(self):
self.router.route(self, "GET") self.router.route(self, self.get_request("GET"))
def do_POST(self): def do_POST(self):
self.router.route(self, "POST") self.router.route(self, self.get_request("POST"))
def get_request(self, method):
url = urlparse(self.path)
return Request(url, method, self.headers)
class Request(object): class Request(object):
def __init__(self, url, method, cookies): def __init__(self, url, method, headers):
self.path = url.path self.path = url.path
self.query = parse_qs(url.query) self.query = parse_qs(url.query)
self.matches = None self.matches = None
self.method = method self.method = method
self.cookies = cookies self.headers = headers
self.cookies = SimpleCookie()
if "Cookie" in headers:
self.cookies.load(headers["Cookie"])
def setMatches(self, matches): def setMatches(self, matches):
self.matches = matches self.matches = matches
@ -114,12 +121,7 @@ class Router(object):
if r.matches(request): if r.matches(request):
return r return r
def route(self, handler, method): def route(self, handler, request):
url = urlparse(handler.path)
cookies = SimpleCookie()
if "Cookie" in handler.headers:
cookies.load(handler.headers["Cookie"])
request = Request(url, method, cookies)
route = self.find_route(request) route = self.find_route(request)
if route is not None: if route is not None:
controller = route.controller controller = route.controller

63
owrx/receiverid.py Normal file
View File

@ -0,0 +1,63 @@
import re
import logging
from owrx.config import Config
logger = logging.getLogger(__name__)
keyRegex = re.compile("^([a-zA-Z]+)-([0-9a-f]{32})-([0-9a-f]{64})$")
keyChallengeRegex = re.compile("^([a-zA-Z]+)-([0-9a-f]{32})-([0-9a-f]{32})$")
headerRegex = re.compile("^ReceiverId (.*)$")
class KeyException(Exception):
pass
class Key(object):
def __init__(self, keyString):
matches = keyRegex.match(keyString)
if not matches:
raise KeyException("invalid key format")
self.source = matches.group(1)
self.id = matches.group(2)
self.secret = matches.group(3)
class KeyChallenge(object):
def __init__(self, challengeString):
matches = keyChallengeRegex.match(challengeString)
if not matches:
raise KeyException("invalid key challenge format")
self.source = matches.group(1)
self.id = matches.group(2)
self.challenge = matches.group(3)
class KeyResponse(object):
def __str__(self):
return "TODO"
class ReceiverId(object):
@staticmethod
def getResponseHeader(requestHeader):
matches = headerRegex.match(requestHeader)
if not matches:
raise KeyException("invalid authorization header")
challenge = KeyChallenge(matches.group(1))
key = ReceiverId.findKey(challenge)
# TODO sign challenge and respond
@staticmethod
def findKey(challenge):
def parseKey(keyString):
try:
return Key(keyString)
except KeyError as e:
logger.error(e)
keys = [key for key in (parseKey(keyString) for keyString in Config.get()['receiver_keys']) if key is not None]
matching_keys = [key for key in keys if key.source == challenge.source and key.id == challenge.id]
if matching_keys:
return matching_keys[0]
return None