Support special characters in passwords

This commit is contained in:
Nick Mowen 2022-10-09 14:03:00 -06:00
parent 82e0a34390
commit 4902ba1e90
4 changed files with 24 additions and 12 deletions

View File

@ -18,7 +18,12 @@ from frigate.const import (
REGEX_CAMERA_NAME, REGEX_CAMERA_NAME,
YAML_EXT, YAML_EXT,
) )
from frigate.util import clean_camera_user_pass, create_mask, deep_merge, load_labels from frigate.util import (
create_mask,
deep_merge,
escape_special_characters,
load_labels,
)
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -694,14 +699,13 @@ class CameraConfig(FrigateBaseModel):
input_args = ( input_args = (
input_args if isinstance(input_args, list) else input_args.split(" ") input_args if isinstance(input_args, list) else input_args.split(" ")
) )
cleaned_input = clean_camera_user_pass(ffmpeg_input.path)
cmd = ( cmd = (
["ffmpeg"] ["ffmpeg"]
+ global_args + global_args
+ hwaccel_args + hwaccel_args
+ input_args + input_args
+ ["-i", cleaned_input] + ["-i", escape_special_characters(ffmpeg_input.path)]
+ ffmpeg_output_args + ffmpeg_output_args
) )

View File

@ -9,4 +9,4 @@ PLUS_API_HOST = "https://api.frigate.video"
# Regex Consts # Regex Consts
REGEX_CAMERA_NAME = "^[a-zA-Z0-9_-]+$" 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_-]+:[a-zA-Z0-9!*'();:@&=+$,?%#_-]+@"

View File

@ -30,6 +30,7 @@ from frigate.const import CLIPS_DIR
from frigate.models import Event, Recordings from frigate.models import Event, Recordings
from frigate.object_processing import TrackedObject, TrackedObjectProcessor from frigate.object_processing import TrackedObject, TrackedObjectProcessor
from frigate.stats import stats_snapshot from frigate.stats import stats_snapshot
from frigate.util import clean_camera_user_pass
from frigate.version import VERSION from frigate.version import VERSION
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -581,7 +582,7 @@ def config():
camera_dict = config["cameras"][camera_name] camera_dict = config["cameras"][camera_name]
camera_dict["ffmpeg_cmds"] = copy.deepcopy(camera.ffmpeg_cmds) camera_dict["ffmpeg_cmds"] = copy.deepcopy(camera.ffmpeg_cmds)
for cmd in camera_dict["ffmpeg_cmds"]: for cmd in camera_dict["ffmpeg_cmds"]:
cmd["cmd"] = " ".join(cmd["cmd"]) cmd["cmd"] = clean_camera_user_pass(" ".join(cmd["cmd"]))
config["plus"] = {"enabled": current_app.plus_api.is_active()} config["plus"] = {"enabled": current_app.plus_api.is_active()}

View File

@ -1,22 +1,16 @@
import copy import copy
import datetime import datetime
import hashlib
import json
import logging import logging
import math
import re import re
import signal import signal
import subprocess as sp
import threading
import time
import traceback import traceback
import urllib.parse
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from collections.abc import Mapping from collections.abc import Mapping
from multiprocessing import shared_memory from multiprocessing import shared_memory
from typing import AnyStr from typing import AnyStr
import cv2 import cv2
import matplotlib.pyplot as plt
import numpy as np import numpy as np
import os import os
import psutil import psutil
@ -630,9 +624,22 @@ def load_labels(path, encoding="utf-8"):
def clean_camera_user_pass(line: str) -> str: def clean_camera_user_pass(line: str) -> str:
"""Removes user and password from line.""" """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, "*:*@", 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]
pw = found[(found.index(":") + 1) :]
logger.error(f"Found {found} and pw {pw}")
return path.replace(pw, urllib.parse.quote_plus(pw))
except AttributeError:
# path does not have user:pass
return path
class FrameManager(ABC): class FrameManager(ABC):
@abstractmethod @abstractmethod
def create(self, name, size) -> AnyStr: def create(self, name, size) -> AnyStr: