Skip to content
This repository has been archived by the owner on Jan 13, 2020. It is now read-only.

Commit

Permalink
receiver receiverid challenge and find corresponding key
Browse files Browse the repository at this point in the history
  • Loading branch information
jketterl committed Jun 10, 2020
1 parent c0f447c commit 61d03b3
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 14 deletions.
14 changes: 10 additions & 4 deletions owrx/controllers/status.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
from . import Controller
from owrx.client import ClientRegistry
from owrx.version import openwebrx_version
from owrx.sdr import SdrService
from owrx.config import Config
import os
from owrx.receiverid import ReceiverId, KeyException
import json
import pkg_resources

import logging

logger = logging.getLogger(__name__)


class StatusController(Controller):
Expand All @@ -27,7 +29,11 @@ def getReceiverStats(self, receiver):

def indexAction(self):
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 = {
"receiver": {
"name": pm["receiver_name"],
Expand Down
22 changes: 12 additions & 10 deletions owrx/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,19 +35,26 @@ def log_message(self, format, *args):
logger.debug("%s - - [%s] %s", self.address_string(), self.log_date_time_string(), format % args)

def do_GET(self):
self.router.route(self, "GET")
self.router.route(self, self.get_request("GET"))

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):
def __init__(self, url, method, cookies):
def __init__(self, url, method, headers):
self.path = url.path
self.query = parse_qs(url.query)
self.matches = None
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):
self.matches = matches
Expand Down Expand Up @@ -114,12 +121,7 @@ def find_route(self, request):
if r.matches(request):
return r

def route(self, handler, method):
url = urlparse(handler.path)
cookies = SimpleCookie()
if "Cookie" in handler.headers:
cookies.load(handler.headers["Cookie"])
request = Request(url, method, cookies)
def route(self, handler, request):
route = self.find_route(request)
if route is not None:
controller = route.controller
Expand Down
63 changes: 63 additions & 0 deletions owrx/receiverid.py
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 61d03b3

Please sign in to comment.