Skip to content

Commit

Permalink
Support more special chars in camera passwords (blakeblackshear#4259)
Browse files Browse the repository at this point in the history
* Support more special chars in camera passwords

* End password test with double @ chars

* Escape passwords in paths for go2rtc

* Fixes for formatting
  • Loading branch information
NateMeyer committed Nov 6, 2022
1 parent 95343b6 commit 40cb510
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 7 deletions.
2 changes: 1 addition & 1 deletion frigate/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@
# Regex Consts

REGEX_CAMERA_NAME = "^[a-zA-Z0-9_-]+$"
REGEX_CAMERA_USER_PASS = "[a-zA-Z0-9_-]+:[a-zA-Z0-9!*'();:@&=+$,?%#_-]+@"
REGEX_CAMERA_USER_PASS = ":\/\/[a-zA-Z0-9_-]+:[\S]+@"
7 changes: 5 additions & 2 deletions frigate/restream.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import logging
import requests
from frigate.util import escape_special_characters

from frigate.config import FrigateConfig

Expand Down Expand Up @@ -34,10 +35,12 @@ def add_cameras(self) -> None:
input.path.startswith("rtsp")
and not camera.restream.force_audio
):
self.relays[cam_name] = input.path
self.relays[cam_name] = escape_special_characters(input.path)
else:
# go2rtc only supports rtsp for direct relay, otherwise ffmpeg is used
self.relays[cam_name] = get_manual_go2rtc_stream(input.path)
self.relays[cam_name] = get_manual_go2rtc_stream(
escape_special_characters(input.path)
)

for name, path in self.relays.items():
params = {"src": path, "name": name}
Expand Down
9 changes: 7 additions & 2 deletions frigate/test/test_camera_pw.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
class TestUserPassCleanup(unittest.TestCase):
def setUp(self) -> None:
self.rtsp_with_pass = "rtsp:https://user:[email protected]:554/live"
self.rtsp_with_special_pass = "rtsp:https://user:password#$@@192.168.0.2:554/live"
self.rtsp_with_special_pass = (
"rtsp:https://user:password`~!@#$%^&*()-_;',.<>:\"\{\}\[\]@@192.168.0.2:554/live"
)
self.rtsp_no_pass = "rtsp:https://192.168.0.3:554/live"

def test_cleanup(self):
Expand All @@ -25,7 +27,10 @@ def test_no_cleanup(self):
def test_special_char_password(self):
"""Test that special characters in pw are escaped, but not others."""
escaped = escape_special_characters(self.rtsp_with_special_pass)
assert escaped == "rtsp:https://user:password%23%24%[email protected]:554/live"
assert (
escaped
== "rtsp:https://user:password%60~%21%40%23%24%25%5E%26%2A%28%29-_%3B%27%2C.%3C%3E%3A%22%5C%7B%5C%7D%5C%5B%5C%5D%[email protected]:554/live"
)

def test_no_special_char_password(self):
"""Test that no change is made to path with no special characters."""
Expand Down
4 changes: 2 additions & 2 deletions frigate/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -635,13 +635,13 @@ def load_labels(path, encoding="utf-8"):
def clean_camera_user_pass(line: str) -> str:
"""Removes user and password from line."""
# todo also remove http password like reolink
return re.sub(REGEX_CAMERA_USER_PASS, "*:*@", line)
return re.sub(REGEX_CAMERA_USER_PASS, ":https://*:*@", line)


def escape_special_characters(path: str) -> str:
"""Cleans reserved characters to encodings for ffmpeg."""
try:
found = re.search(REGEX_CAMERA_USER_PASS, path).group(0)[:-1]
found = re.search(REGEX_CAMERA_USER_PASS, path).group(0)[3:-1]
pw = found[(found.index(":") + 1) :]
return path.replace(pw, urllib.parse.quote_plus(pw))
except AttributeError:
Expand Down

0 comments on commit 40cb510

Please sign in to comment.