From 6f614c91d7c64c1c6160e83b9b3705fd063be4fd Mon Sep 17 00:00:00 2001 From: ludeeus Date: Thu, 15 Jun 2023 16:57:53 +0000 Subject: [PATCH] Quote CIFS password to remove strict requirements --- supervisor/mounts/mount.py | 3 ++- supervisor/mounts/validate.py | 8 +++----- tests/mounts/test_mount.py | 6 +++--- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/supervisor/mounts/mount.py b/supervisor/mounts/mount.py index e08a00e4b..40b24b13a 100644 --- a/supervisor/mounts/mount.py +++ b/supervisor/mounts/mount.py @@ -358,7 +358,8 @@ class CIFSMount(NetworkMount): def options(self) -> list[str]: """Options to use to mount.""" return ( - super().options + [f"username={self.username}", f"password={self.password}"] + super().options + + [f"username={self.username}", f"password='{self.password}'"] if self.username else [] ) diff --git a/supervisor/mounts/validate.py b/supervisor/mounts/validate.py index 1786a5282..e20ff48ed 100644 --- a/supervisor/mounts/validate.py +++ b/supervisor/mounts/validate.py @@ -21,13 +21,11 @@ from .const import ( RE_MOUNT_NAME = re.compile(r"^\w+$") RE_PATH_PART = re.compile(r"^[^\\\/]+") -RE_MOUNT_OPTION = re.compile(r"^[^,=]+$") VALIDATE_NAME = vol.Match(RE_MOUNT_NAME) VALIDATE_SERVER = vol.Match(RE_PATH_PART) VALIDATE_SHARE = vol.Match(RE_PATH_PART) -VALIDATE_USERNAME = vol.Match(RE_MOUNT_OPTION) -VALIDATE_PASSWORD = vol.Match(RE_MOUNT_OPTION) + _SCHEMA_BASE_MOUNT_CONFIG = vol.Schema( { @@ -49,8 +47,8 @@ SCHEMA_MOUNT_CIFS = _SCHEMA_MOUNT_NETWORK.extend( { vol.Required(ATTR_TYPE): MountType.CIFS.value, vol.Required(ATTR_SHARE): VALIDATE_SHARE, - vol.Inclusive(ATTR_USERNAME, "basic_auth"): VALIDATE_USERNAME, - vol.Inclusive(ATTR_PASSWORD, "basic_auth"): VALIDATE_PASSWORD, + vol.Inclusive(ATTR_USERNAME, "basic_auth"): str, + vol.Inclusive(ATTR_PASSWORD, "basic_auth"): str, } ) diff --git a/tests/mounts/test_mount.py b/tests/mounts/test_mount.py index 24183686a..06d4d804a 100644 --- a/tests/mounts/test_mount.py +++ b/tests/mounts/test_mount.py @@ -39,7 +39,7 @@ async def test_cifs_mount( "server": "test.local", "share": "camera", "username": "admin", - "password": "password", + "password": "p@assword!,=", } mount: CIFSMount = Mount.from_dict(coresys, mount_data) @@ -54,7 +54,7 @@ async def test_cifs_mount( assert mount.what == "//test.local/camera" assert mount.where == Path("/mnt/data/supervisor/mounts/test") assert mount.local_where == tmp_supervisor_data / "mounts" / "test" - assert mount.options == ["username=admin", "password=password"] + assert mount.options == ["username=admin", "password='p@assword!,='"] assert not mount.local_where.exists() assert mount.to_dict(skip_secrets=False) == mount_data @@ -73,7 +73,7 @@ async def test_cifs_mount( "mnt-data-supervisor-mounts-test.mount", "fail", [ - ["Options", Variant("s", "username=admin,password=password")], + ["Options", Variant("s", "username=admin,password='p@assword!,='")], ["Type", Variant("s", "cifs")], ["Description", Variant("s", "Supervisor cifs mount: test")], ["What", Variant("s", "//test.local/camera")],