Unverified Commit 3367797b authored by emilylange's avatar emilylange
Browse files

music-assistant: fix running the built-in snapcast server

This patch fixes two issues that would otherwise prevent the built-in
snapserver to run. Running music-assistant with an external snapserver
is not affected by those.

1. snapserver prior to v0.30.0 allowed arbitrary code execution in the
AddStream (and RemoveStream) JSON RPC API method that music-assistant
uses to load a custom control script (plugin). To fix this rather
severe vulnerability, snapserver v0.30.0 removed those affected methods
altogether, only for them to return with new security measures in
v0.31.0. Most relevant for us and this patch, the control script must
be located in the [stream].plugin_dir now, which is unset by default.
So to be able to load the control script music-assistant uses for the
built-in snapserver, we simply pass --stream.plugin_dir with the correct
directory as parameter when starting snapserver

2. snapserver exits with an error message on start up when it
cannot read the configuration file since v0.32.0. To fix this, we
tell snapserver to read /dev/null as config instead of the default
(non-existent) /etc/snapserver.conf
parent 275b511f
Loading
Loading
Loading
Loading
+33 −0
Original line number Diff line number Diff line
diff --git a/music_assistant/providers/snapcast/__init__.py b/music_assistant/providers/snapcast/__init__.py
index 742d798183ec6fd1ac1fdbcad750912c222de5c3..8d0d95577d31f735977884280b08f384187774bd 100644
--- a/music_assistant/providers/snapcast/__init__.py
+++ b/music_assistant/providers/snapcast/__init__.py
@@ -87,7 +87,8 @@ DEFAULT_SNAPSTREAM_IDLE_THRESHOLD = 60000
 MASS_STREAM_PREFIX = "Music Assistant - "
 MASS_ANNOUNCEMENT_POSTFIX = " (announcement)"
 SNAPWEB_DIR = pathlib.Path(__file__).parent.resolve().joinpath("snapweb")
-CONTROL_SCRIPT = pathlib.Path(__file__).parent.resolve().joinpath("control.py")
+CONTROL_SCRIPT_DIR = pathlib.Path(__file__).parent.resolve()
+CONTROL_SCRIPT = CONTROL_SCRIPT_DIR.joinpath("control.py")
 
 DEFAULT_SNAPCAST_FORMAT = AudioFormat(
     content_type=ContentType.PCM_S16LE,
@@ -866,6 +867,10 @@ class SnapCastProvider(PlayerProvider):
 
         args = [
             "snapserver",
+            # defaults to /etc/snapcast.conf but needs
+            # to exist in order for snapserver to start
+            # https://github.com/badaix/snapcast/issues/1402
+            "--config=/dev/null",
             # config settings taken from
             # https://raw.githubusercontent.com/badaix/snapcast/86cd4b2b63e750a72e0dfe6a46d47caf01426c8d/server/etc/snapserver.conf
             f"--server.datadir={self.mass.storage_path}",
@@ -878,6 +883,7 @@ class SnapCastProvider(PlayerProvider):
             f"--stream.buffer={self._snapcast_server_buffer_size}",
             f"--stream.chunk_ms={self._snapcast_server_chunk_ms}",
             f"--stream.codec={self._snapcast_server_transport_codec}",
+            f"--stream.plugin_dir={CONTROL_SCRIPT_DIR}",
             f"--stream.send_to_muted={str(self._snapcast_server_send_to_muted).lower()}",
             f"--streaming_client.initial_volume={self._snapcast_server_initial_volume}",
         ]
+3 −0
Original line number Diff line number Diff line
@@ -68,6 +68,9 @@ python.pkgs.buildPythonApplication rec {

    # Disable interactive dependency resolution, which clashes with the immutable Python environment
    ./dont-install-deps.patch

    # Fix running the built-in snapcast server
    ./builtin-snapcast-server.patch
  ];

  postPatch = ''