dtcooper / raspotify

A Spotify Connect client that mostly Just Works™
https://dtcooper.github.io/raspotify
MIT License
4.63k stars 213 forks source link

The current config situation is insecure. #460

Closed JasonLG1979 closed 2 years ago

JasonLG1979 commented 2 years ago

Currently if a user puts their username and password in /etc/default/raspotify it is passed to librespot via a command line arg.

systemctl status raspotify does not require elevated privileges so anyone can call it and see the user credentials in plain text.

I wouldn't call this a threat level 11 situation as I'm guessing most people use Raspotify in more of an appliance situation as apposed to in a multi-user setup, and this isn't an upstream bug, more of a limitation, but there is a better way.

The solution involves this upstream PR which adds the ability to parse environment variables to librespot and a potentially painful transition to a better configuration model.

Currently the settings in /etc/default/raspotify aren't "real" environment variables they're more just "arg buckets" that you can put really anything you want in with a few exceptions.

After environment variable parsing is merged into librespot /etc/default/raspotify will be made a "real" environment file meaning the variables won't be "arg buckets" anymore but actual real libresot environment variable that would map one to one to librespot flags and options.

That means everything but the default device name (so we can pickup the hostname) will be moved to /etc/default/raspotify and nothing passed to librespot will be visible with systemctl status raspotify.

What this means for users is that in some future update you may be required to reconfigure Raspotify as there really isn't a good automatic way to migrate.

JasonLG1979 commented 2 years ago

The new /etc/default/raspotify would look something like this:

# /etc/default/raspotify -- Arguments/configuration for librespot

# A non-exhaustive list of librespot options and flags.

# You can find a full list with `librespot -h`.

# To avoid name collisions environment variables must be prepended with
# `LIBRESPOT_`, so option/flag `foo-bar` becomes `LIBRESPOT_FOO_BAR`.

# Invalid environment variables will be ignored.

# Raspotify defaults may vary from librespot defaults.
# Commenting out the environment variable will fallback to librespot's default.

# Flags are either on (uncommented) or off (commented),
# their values are otherwise not evaluated (but the "=" is still needed).

# Only log warning and error messages.
LIBRESPOT_QUIET=

# Disable caching of the audio data.
#LIBRESPOT_DISABLE_AUDIO_CACHE=

# Disable caching of credentials.
#LIBRESPOT_DISABLE_CREDENTIAL_CACHE=

# Disable zeroconf discovery mode.
#LIBRESPOT_DISABLE_DISCOVERY=

# Automatically play similar songs when your music ends.
LIBRESPOT_AUTOPLAY= 

# Play all tracks at approximately the same apparent volume.
LIBRESPOT_ENABLE_VOLUME_NORMALISATION=

# Options will fallback to their defaults if commented out,
# otherwise they must have a valid value.

#Device name. Raspotify defaults to "Raspotify (%H)" *HostName.
#LIBRESPOT_NAME="Raspotify"

# Bitrate (kbps) {96|160|320}. Defaults to 160.
#LIBRESPOT_BITRATE="160"

# Output format {F64|F32|S32|S24|S24_3|S16}. Defaults to S16.
#LIBRESPOT_FORMAT="S16"

# Displayed device type. Defaults to speaker.
#LIBRESPOT_DEVICE_TYPE="speaker"

# Path to a directory where files will be cached.
# Uncomment to use a cache for downloaded audio files.
# No other directory can be used without changes to the systemd unit file.
# Cache is disabled by default. 
#LIBRESPOT_CACHE="/var/cache/raspotify"

# Limits the size of the cache for audio files.
# It's possible to use suffixes like K, M or G, e.g. 16G for example.
#LIBRESPOT_CACHE_SIZE_LIMIT=""

# Audio backend to use, alsa or pipe. Defaults to alsa.
#LIBRESPOT_BACKEND="alsa"

# Username used to sign in with.
# Credentials are not required if LIBRESPOT_DISABLE_DISCOVERY is not set.
#LIBRESPOT_USERNAME=""

# Password used to sign in with.
#LIBRESPOT_PASSWORD=""

# Audio device to use, use `librespot --device ?` to list options.
# Defaults to the system's default.
#LIBRESPOT_DEVICE="default"

# Initial volume in % from 0 - 100.
# Raspotify defaults to 100 For the alsa mixer: the current volume.
LIBRESPOT_INITIAL_VOLUME="100"

# Volume control scale type {cubic|fixed|linear|log}.
# Raspotify defaults to cubic.
# Cubic is very similar to log but with more top-end granularity.
# PulseAudio uses cubic by default for example.
LIBRESPOT_VOLUME_CTRL="cubic"

# Range of the volume control (dB) from 0.0 to 100.0.
# Default for softvol: 60.0.
# For the alsa mixer: what the control supports.
#LIBRESPOT_VOLUME_RANGE="60.0"

# Pregain (dB) applied by volume normalisation from -10.0 to 10.0.
# Defaults to 0.0.
#LIBRESPOT_NORMALISATION_PREGAIN="0.0"

# Threshold (dBFS) at which point the dynamic limiter engages
# to prevent clipping from 0.0 to -10.0.
# Defaults to -2.0.
#LIBRESPOT_NORMALISATION_THRESHOLD="-2.0"

# The port the internal server advertises over zeroconf 1 - 65535.
# Ports <= 1024 may require root privileges.
#LIBRESPOT_ZEROCONF_PORT=""

# HTTP proxy to use when connecting.
#LIBRESPOT_PROXY=""
JasonLG1979 commented 2 years ago

I suppose now is also a time to talk about defaults. I'm interested in hearing from users about sensible defaults.

kirenida commented 2 years ago

I suppose now is also a time to talk about defaults. I'm interested in hearing from users about sensible defaults.

I usually change the quality to 320, disable normalization and lower the default volume to 80. So I would say the current defaults are sensible, at least in my case.

JasonLG1979 commented 2 years ago

@kirenida I've deviated from the current defaults in the above /etc/default/raspotify by these settings:

  1. I've added --autoplay.

It seems like most people would want or expect that to be the default and might not realize that it's a client side setting (in fact it's kinda weird that it actually is?) and not something that's set from the controlling device.

  1. I've added --quiet.

By default the libresopt logs are pretty noisy. This makes it so librespot only logs warnings and errors.

  1. I've changed the default volume scaling from linear :vomiting_face: to cubic.

As noted in the config cubic is very close to logarithmic (your standard volume pot is log, it can also be set to log) except that cubic has a slightly more "useful" top-end. PulseAudio for example uses cubic so I feel like it will be a good fit and familiar to people coming from desktop Linux.

kirenida commented 2 years ago

@JasonLG1979 That looks OK. Don't know what else to say :)

As I don't have experience with other Spotify Connect devices, I don't know what their defaults are or what other ("normal") people consider sane. I think that anybody who is capable of using a Raspberry and installing Raspotify should already have an idea of how to change settings to their liking or findo out how to do it. But now I'm starting to generalize so I will stop.

Current defaults are OK (for my idea of an average user), your changes look OK as sane defaults, we have simple access for any options that we would want to configure, and that's it.

JasonLG1979 commented 2 years ago

Yep. I don't have any experience with any other dedicated Connect device either. I was just going off what I would expect. And I agree that even though Raspotify is pretty easy to install it's still very much a "batteries not included" situation. Users are going to have to roll up their sleeves a bit and read a wiki page or 2.

JasonLG1979 commented 2 years ago

I'm also not sure that /etc/default is the right place for a config file?

jgabriel98 commented 2 years ago

I suppose now is also a time to talk about defaults. I'm interested in hearing from users about sensible defaults.

I think LIBRESPOT_VOLUME_RANGEcould be 100 or 86 (equivalent to dB gain = 0,00) instead of 60 (equivalent to dB gain = -9,01).

I don't like the idea to change the volume gain by default. Or is there any reason to do this?

JasonLG1979 commented 2 years ago

LIBRESPOT_VOLUME_RANGE is not the gain.

jgabriel98 commented 2 years ago

LIBRESPOT_VOLUME_RANGE is not the gain.

You're totally right, my bad.