Add access key gating to incoming streams

For the moment this is a singleton. One access key will let you stream
to any app or stream key. It's denoted in the form of appending a GET
parameter to the URL like `?access_key=foobarbaz`

This at least means someone who knows the stream URL (frex to view it)
won't also be able to stream.
This commit is contained in:
Trysdyn Black 2025-02-16 17:06:35 -08:00
parent c934bedd44
commit 4c2c82cfc3
3 changed files with 24 additions and 3 deletions

View file

@ -45,7 +45,7 @@ def webhook_offline() -> None:
requests.post(config.WEBHOOK_URL, timeout=10, json=data, headers=config.WEBHOOK_HEADERS)
def check_authorized(host, app, stream, source) -> bool:
def check_authorized(host, app, stream, source, access_key) -> bool:
# Are we globally disabled?
if config.DISABLED:
return False
@ -57,7 +57,10 @@ def check_authorized(host, app, stream, source) -> bool:
if f"default:{app}:{stream}" in config.DISABLED_KEYS:
return False
# Finally check the provided vhost app/stream
return f"{host}:{app}:{stream}" not in config.DISABLED_KEYS
if f"{host}:{app}:{stream}" in config.DISABLED_KEYS:
return False
# Check for an access key requirement
return not (config.ACCESS_KEY and access_key != config.ACCESS_KEY)
@cherrypy.tools.register("on_end_request")
@ -124,6 +127,16 @@ class Admission:
_, _, host, app, path = input_json["request"]["url"].split("/")[:5]
stream = path.split("?")[0]
# Tokenize out URL GET parameters
params = {}
if "?" in path:
for pair in path.split("?")[1].split("&"):
if "=" in pair:
k, v = pair.split("=", 1)
params[k] = v
else:
params[pair] = None
# Populate variables for our on_end_request tool into request object
cherrypy.request.update_stream = ("default", app, stream)
@ -136,7 +149,7 @@ class Admission:
ip = input_json["client"]["real_ip"]
# Check if stream is authorized
if not check_authorized(host, app, stream, ip):
if not check_authorized(host, app, stream, ip, params.get("access_key")):
cherrypy.log(f"Unauthorized stream key: {app}/{stream}")
return {"allowed": False}