librespot-org / librespot

Open Source Spotify client library
MIT License
4.73k stars 577 forks source link

Authentication failures #1308

Closed dspearson closed 1 day ago

dspearson commented 1 month ago

"ERROR librespot] Connection failed: Login failed with reason: Bad credentials"

Credentials are valid.

I assume Spotify has changed the login flow. This affects upstream projects using librespot also, looking at their buglists.

kingosticks commented 1 month ago

It appears to be for some users only. It's still working for me right now. So reproducing it (to debug it) might not be so simple (yet).

azel1 commented 1 month ago

The same code gives bad credentials error on my linux machine, but works everytime on Windows. Tried multiple accounts.

quantverse commented 1 month ago

Same problem on my Linux machine since today. Yesterday it was still working fine.

Ubuntu 22.04.

roderickvd commented 1 month ago

For the record, which version of librespot? 0.4? dev? Those downstream packages use 0.4 I presume. Please try them both. I remember I made some changes on it to dev.

Re: @kingosticks would also not be the first time that something gets broken / changed on Spotify's end, only to have it restored the day or week after.

Anyway, having it work on one platform and not the other is fishy.

eladyn commented 1 month ago

I tried 0.4.2, dev and one of the proposed login5 changes, but all of them are broken for me. (although reconsidering what currently seems to be broken, the login5 thing should indeed not have much effect)

andrewCohn commented 1 month ago

0.5.0-dev is also affected on Arch kernel version 6.9.7.

Immediately after posting this, I tried again, and it just worked? I'm not entirely sure what changed; my systemctl script hasn't changed, but after a number of auto-restarts, it came back authenticated? Very strange!

Losses commented 1 month ago

Same issue here

ERROR librespot] could not initialize spirc: Permission denied { Login failed with reason: Bad credentials }
Geral3 commented 1 month ago

Same Here

2024-07-30T05:43:24.314571Z  WARN spotify_player::auth: Failed to authenticate: Login failed with reason: Bad credentials
dspearson commented 1 month ago

FWIW, the original bug report was made against latest dev on a Debian system that previously was working fine, with no new packages installed since breaking. (I built from git initially to see if it was fixed upstream.)

Feel free to reach out if you need any assistance to debug the issue, I'd be happy to help.

roderickvd commented 1 month ago

Given it's working on Windows, what if you change this line: https://github.com/librespot-org/librespot/blob/299b7dec20b45b9fa19a4a46252079e8a8b7a8ba/core/src/connection/mod.rs#L91

To pretend that it's always Windows?

You may need to do the same here: https://github.com/librespot-org/librespot/blob/299b7dec20b45b9fa19a4a46252079e8a8b7a8ba/core/src/connection/handshake.rs#L113

Then in dev there's a similar thing in the HTTP client, but when you're authenticating, that's not yet where you are in the code flow.

It's the only thing I can now think of why it would work on Windows but not on Linux.

IVIanuu commented 1 month ago

Same issue here.

Losses commented 1 month ago

@roderickvd Quickly checked the solution, not working, sadly.

librespot_core::session] Connecting to A[2024-07-30T07:32:37Z ERROR librespot] could not initialize spirc: Permission denied { Login failed with reason: Bad credentials }

System: NixOS 24.05.20240727.8c50662 (Uakari) x86_64

roderickvd commented 1 month ago

Reporters, please add the access point / servers you are connecting to:

I'm reading that the issue is on Windows also, so let's try to triangulate what's happening. Are officially supported devices from the past (like stereo receivers, old Sonos thingies, whatever) also having issues?

ssamjh commented 1 month ago

Getting this in New Zealand, using librespot-java v1.6.3 on Windows 10.

Using USER_PASS auth.

2024-07-30 19:45:17,085 DEBUG TimeProvider:90 - Loaded time offset from NTP: 1115ms 2024-07-30 19:45:18,142 INFO ApResolver:99 - Loaded aps into pool: {accesspoint=[ap-gae2.spotify.com:4070, ap-gae2.spotify.com:443, ap-gae2.spotify.com:80, ap-guc3.spotify.com:4070, ap-gue1.spotify.com:443, ap-gew4.spotify.com:80], dealer=[gae2-dealer2.spotify.com:443, guc3-dealer2.spotify.com:443, gue1-dealer2.spotify.com:443, gew4-dealer2.spotify.com:443], spclient=[gae2-spclient.spotify.com:443, guc3-spclient.spotify.com:443, gue1-spclient.spotify.com:443, gew4-spclient.spotify.com:443]} 2024-07-30 19:45:18,359 INFO Session:140 - Created new session! {deviceId: <snip>, ap: ap-guc3.spotify.com:4070, proxy: false} 2024-07-30 19:45:19,194 INFO Session:334 - Connected successfully! 2024-07-30 19:45:19,647 ERROR Log4JUncaughtExceptionHandler:31 - [main] xyz.gianlu.librespot.core.Session$SpotifyAuthenticationException: BadCredentials at xyz.gianlu.librespot.core.Session.authenticatePartial(Session.java:453) ~[librespot-api-1.6.3.jar:1.6.3] at xyz.gianlu.librespot.core.Session.authenticate(Session.java:342) ~[librespot-api-1.6.3.jar:1.6.3] at xyz.gianlu.librespot.core.Session.access$600(Session.java:77) ~[librespot-api-1.6.3.jar:1.6.3] at xyz.gianlu.librespot.core.Session$Builder.create(Session.java:1057) ~[librespot-api-1.6.3.jar:1.6.3] at xyz.gianlu.librespot.api.Main.withPlayer(Main.java:53) ~[librespot-api-1.6.3.jar:1.6.3] at xyz.gianlu.librespot.api.Main.main(Main.java:45) ~[librespot-api-1.6.3.jar:1.6.3]

Losses commented 1 month ago

@roderickvd

Server:

ap-gew1.spotify.com

Ping Result:

PING ap-gew1.spotify.com (104.199.65.124) 56(84) bytes of data.
64 bytes from 124.65.199.104.bc.googleusercontent.com (104.199.65.124): icmp_seq=1 ttl=52 time=278 ms
noahhaon commented 1 month ago

From a raspberry pi 4 running LibreELEC:

# librespot --bitrate 320 --device-type tv --disable-audio-cache --disable-credential-cache --name Librespot@LibreELEC --onevent onevent.py --quiet -A on -u [REDACTED] -p [REDACTED]-O -v --backend pulseaudio --device librespot

[2024-07-30T08:08:36Z WARN  librespot] `--verbose` and `--quiet` are mutually exclusive. Logging can not be both verbose and quiet. Using verbose mode.
[2024-07-30T08:08:36Z INFO  librespot] librespot 0.5.0-dev 4513878 (Built on 2024-04-24, Build ID: YmZq6K14, Profile: release)
[2024-07-30T08:08:36Z TRACE librespot] Command line argument(s):
[2024-07-30T08:08:36Z TRACE librespot]          bitrate "320"
[2024-07-30T08:08:36Z TRACE librespot]          device-type "tv"
[2024-07-30T08:08:36Z TRACE librespot]          disable-audio-cache
[2024-07-30T08:08:36Z TRACE librespot]          disable-credential-cache
[2024-07-30T08:08:36Z TRACE librespot]          name "Librespot@LibreELEC"
[2024-07-30T08:08:36Z TRACE librespot]          onevent "onevent.py"
[2024-07-30T08:08:36Z TRACE librespot]          quiet
[2024-07-30T08:08:36Z TRACE librespot]          A "on"
[2024-07-30T08:08:36Z TRACE librespot]          u "XXXXXXXX"
[2024-07-30T08:08:36Z TRACE librespot]          p "XXXXXXXX"
[2024-07-30T08:08:36Z TRACE librespot]          O
[2024-07-30T08:08:36Z TRACE librespot]          v
[2024-07-30T08:08:36Z TRACE librespot]          backend "pulseaudio"
[2024-07-30T08:08:36Z TRACE librespot]          device "librespot"
[2024-07-30T08:08:36Z DEBUG librespot_core::session] new Session
[2024-07-30T08:08:36Z INFO  librespot_playback::mixer::softmixer] Mixing with softvol and volume control: Log(60.0)
[2024-07-30T08:08:36Z DEBUG librespot_playback::player] new Player [0]
[2024-07-30T08:08:36Z INFO  librespot_playback::convert] Converting with ditherer: tpdf
[2024-07-30T08:08:36Z INFO  librespot_playback::audio_backend::pulseaudio] Using PulseAudioSink with format: S16
[2024-07-30T08:08:36Z DEBUG librespot_connect::spirc] new Spirc[0]
[2024-07-30T08:08:36Z DEBUG librespot::component] new MercuryManager
[2024-07-30T08:08:36Z DEBUG librespot::component] new ApResolver
[2024-07-30T08:08:36Z DEBUG librespot_core::http_client] Requesting https://apresolve.spotify.com/?type=accesspoint&type=dealer&type=spclient
[2024-07-30T08:08:36Z DEBUG librespot_playback::player] command=AddEventSender
[2024-07-30T08:08:36Z INFO  librespot_core::session] Connecting to AP "ap-gew4.spotify.com:4070"
[2024-07-30T08:08:37Z ERROR librespot] could not initialize spirc: Permission denied { Login failed with reason: Bad credentials }

# nslookup ap-gew4.spotify.com
Server:    xxx
Address 1: xxx

Name:      ap-gew4.spotify.com
Address 1: 34.158.0.131 131.0.158.34.bc.googleusercontent.com
erkr commented 1 month ago

It appears to be for some users only. It's still working for me right now.

Probably it happens once your token expires

rgon commented 1 month ago

Using librespot-java and USER_PASS auth ap: ap-gue1.spotify.com Ping result:

PING ap-gew1.spotify.com (104.199.65.124) 56(84) bytes of data.
64 bytes from 124.65.199.104.bc.googleusercontent.com (104.199.65.124): icmp_seq=1 ttl=104 time=33.0 ms
Full log
spotifyd     | 2024-07-30 08:33:28,288 INFO  ApResolver:99 - Loaded aps into pool: {accesspoint=[ap-gew1.spotify.com:4070, ap-gew1.spotify.com:443, ap-gew1.spotify.com:80, ap-guc3.spotify.com:4070, ap-gue1.spotify.com:443, ap-gae2.spotify.com:80], dealer=[gew1-dealer2.spotify.com:443, guc3-dealer2.spotify.com:443, gue1-dealer2.spotify.com:443, gae2-dealer2.spotify.com:443], spclient=[gew1-spclient.spotify.com:443, guc3-spclient.spotify.com:443, gue1-spclient.spotify.com:443, gae2-spclient.spotify.com:443]}
spotifyd     | 2024-07-30 08:33:28,441 INFO  Session:140 - Created new session! {deviceId: , ap: ap-gue1.spotify.com:443, proxy: false} 
spotifyd     | 2024-07-30 08:33:29,092 INFO  Session:334 - Connected successfully!
spotifyd     | 2024-07-30 08:33:29,421 ERROR Log4JUncaughtExceptionHandler:31 - [main]
spotifyd     | xyz.gianlu.librespot.core.Session$SpotifyAuthenticationException: BadCredentials
spotifyd     |  at xyz.gianlu.librespot.core.Session.authenticatePartial(Session.java:453) ~[librespot:1.6.3]
spotifyd     |  at xyz.gianlu.librespot.core.Session.authenticate(Session.java:342) ~[librespot:1.6.3]
spotifyd     |  at xyz.gianlu.librespot.core.Session.access$600(Session.java:77) ~[librespot:1.6.3]
spotifyd     |  at xyz.gianlu.librespot.core.Session$Builder.create(Session.java:1057) ~[librespot:1.6.3]
spotifyd     |  at xyz.gianlu.librespot.player.Main.main(Main.java:80) ~[librespot:1.6.3]
spotifyd     | 2024-07-30 08:34:30,706 INFO  ApResolver:99 - Loaded aps into pool: {accesspoint=[ap-gew1.spotify.com:4070, ap-gew1.spotify.com:443, ap-gew1.spotify.com:80, ap-guc3.spotify.com:4070, ap-gue1.spotify.com:443, ap-gew4.spotify.com:80], dealer=[gew1-dealer2.spotify.com:443, guc3-dealer2.spotify.com:443, gue1-dealer2.spotify.com:443, gew4-dealer2.spotify.com:443], spclient=[gew1-spclient.spotify.com:443, guc3-spclient.spotify.com:443, gue1-spclient.spotify.com:443, gew4-spclient.spotify.com:443]}
spotifyd     | 2024-07-30 08:34:30,759 INFO  Session:140 - Created new session! {deviceId: , ap: ap-gew1.spotify.com:443, proxy: false} 
spotifyd     | 2024-07-30 08:34:31,235 INFO  Session:334 - Connected successfully!
spotifyd     | 2024-07-30 08:34:31,429 ERROR Log4JUncaughtExceptionHandler:31 - [main]
spotifyd     | xyz.gianlu.librespot.core.Session$SpotifyAuthenticationException: BadCredentials
spotifyd     |  at xyz.gianlu.librespot.core.Session.authenticatePartial(Session.java:453) ~[librespot:1.6.3]
spotifyd     |  at xyz.gianlu.librespot.core.Session.authenticate(Session.java:342) ~[librespot:1.6.3]
spotifyd     |  at xyz.gianlu.librespot.core.Session.access$600(Session.java:77) ~[librespot:1.6.3]
spotifyd     |  at xyz.gianlu.librespot.core.Session$Builder.create(Session.java:1057) ~[librespot:1.6.3]
spotifyd     |  at xyz.gianlu.librespot.player.Main.main(Main.java:80) ~[librespot:1.6.3]
bitclick commented 1 month ago
librespot 0.4.2 a6e1258 (Built on 2023-06-21, Build ID: AEkvVEBq, Profile: release)
Debian GNU/Linux 11

i am affected too, since 2024-07-29T09:37:23Z (in germany) see attached logfile for connection attempts and servers (before and after the error started happening) librespot-connection-attempts.log

PING ap-guc3.spotify.com (104.154.127.126) 56(84) bytes of data.
64 bytes from 126.127.154.104.bc.googleusercontent.com (104.154.127.126): icmp_seq=1 ttl=56 time=125 ms

UPDATE:

dspearson commented 1 month ago

Unfortunately changing the OS in the match clauses as suggested did nothing.

❯ ./target/debug/librespot --verbose  --username=XXXXXXXX --password=XXXXXXXX
[2024-07-30T08:47:26Z INFO  librespot] librespot 0.5.0-dev 299b7de (Built on 2024-07-30, Build ID: j5Xsh0Yw, Profile: debug)
[2024-07-30T08:47:26Z TRACE librespot] Command line argument(s):
[2024-07-30T08:47:26Z TRACE librespot]          verbose
[2024-07-30T08:47:26Z TRACE librespot]          username "XXXXXXXX"
[2024-07-30T08:47:26Z TRACE librespot]          password "XXXXXXXX"
[2024-07-30T08:47:26Z DEBUG librespot_core::session] new Session
[2024-07-30T08:47:26Z DEBUG librespot_discovery::server] Zeroconf server listening on 0.0.0.0:32987
[2024-07-30T08:47:26Z INFO  librespot_playback::mixer::softmixer] Mixing with softvol and volume control: Log(60.0)
[2024-07-30T08:47:26Z DEBUG librespot_connect::spirc] new Spirc[0]
[2024-07-30T08:47:26Z DEBUG librespot::component] new MercuryManager
[2024-07-30T08:47:26Z DEBUG librespot_playback::player] new Player [0]
[2024-07-30T08:47:26Z DEBUG librespot::component] new ApResolver
[2024-07-30T08:47:26Z INFO  librespot_playback::convert] Converting with ditherer: tpdf
[2024-07-30T08:47:26Z INFO  librespot_playback::audio_backend::rodio] Using Rodio sink with format S16 and cpal host: ALSA
[2024-07-30T08:47:26Z INFO  librespot_playback::audio_backend::rodio] Using audio device: default
[2024-07-30T08:47:26Z DEBUG librespot_core::http_client] Requesting https://apresolve.spotify.com/?type=accesspoint&type=dealer&type=spclient
[2024-07-30T08:47:26Z DEBUG librespot_playback::audio_backend::rodio] Rodio sink was created
[2024-07-30T08:47:26Z INFO  librespot_core::session] Connecting to AP "ap-gew4.spotify.com:4070"
[2024-07-30T08:47:26Z ERROR librespot] could not initialize spirc: Permission denied { Login failed with reason: Bad credentials }

❯ dig +short A ap-gew4.spotify.com
34.158.0.131
BGazotti commented 1 month ago

Same here in São Paulo, Brazil, stopped working yesterday afternoon. 6.10.2 kernel on Gentoo.


$ librespot -u not-so-secret-username -p super-secret-password --enable-volume-normalisation --format F32 --normalisation-pregain=-5.5 --autoplay on --name librespot --bitrate 320 --device-type computer -v --backend pulseaudio 2>&1

[2024-07-30T08:55:43Z INFO  librespot] librespot 0.5.0-dev 299b7de (Built on 2024-07-29, Build ID: 9yMh5PUy, Profile: release)
[2024-07-30T08:55:43Z TRACE librespot] Command line argument(s):
[2024-07-30T08:55:43Z TRACE librespot]      u "XXXXXXXX"
[2024-07-30T08:55:43Z TRACE librespot]      p "XXXXXXXX"
[2024-07-30T08:55:43Z TRACE librespot]      enable-volume-normalisation
[2024-07-30T08:55:43Z TRACE librespot]      format "F32"
[2024-07-30T08:55:43Z TRACE librespot]      normalisation-pregain "-5.5"
[2024-07-30T08:55:43Z TRACE librespot]      autoplay "on"
[2024-07-30T08:55:43Z TRACE librespot]      name "librespot"
[2024-07-30T08:55:43Z TRACE librespot]      bitrate "320"
[2024-07-30T08:55:43Z TRACE librespot]      device-type "computer"
[2024-07-30T08:55:43Z TRACE librespot]      v
[2024-07-30T08:55:43Z TRACE librespot]      backend "pulseaudio"
[2024-07-30T08:55:43Z DEBUG librespot_core::session] new Session
[2024-07-30T08:55:43Z DEBUG librespot_discovery::server] Zeroconf server listening on 0.0.0.0:38875
[2024-07-30T08:55:43Z INFO  librespot_playback::mixer::softmixer] Mixing with softvol and volume control: Log(60.0)
[2024-07-30T08:55:43Z DEBUG librespot_playback::player] Normalisation Type: Auto
[2024-07-30T08:55:43Z DEBUG librespot_playback::player] Normalisation Pregain: -5.5 dB
[2024-07-30T08:55:43Z DEBUG librespot_playback::player] Normalisation Threshold: -2.0 dBFS
[2024-07-30T08:55:43Z DEBUG librespot_playback::player] Normalisation Method: Dynamic
[2024-07-30T08:55:43Z DEBUG librespot_playback::player] Normalisation Attack: 5 ms
[2024-07-30T08:55:43Z DEBUG librespot_playback::player] Normalisation Release: 100 ms
[2024-07-30T08:55:43Z DEBUG librespot_playback::player] Normalisation Knee: 5 dB
[2024-07-30T08:55:43Z DEBUG librespot_connect::spirc] new Spirc[0]
[2024-07-30T08:55:43Z DEBUG librespot::component] new MercuryManager
[2024-07-30T08:55:43Z DEBUG librespot::component] new ApResolver
[2024-07-30T08:55:43Z DEBUG librespot_core::http_client] Requesting https://apresolve.spotify.com/?type=accesspoint&type=dealer&type=spclient
[2024-07-30T08:55:43Z DEBUG librespot_playback::player] new Player [0]
[2024-07-30T08:55:43Z INFO  librespot_playback::audio_backend::pulseaudio] Using PulseAudioSink with format: F32
[2024-07-30T08:55:43Z INFO  librespot_core::session] Connecting to AP "ap-gue1.spotify.com:4070"
[2024-07-30T08:55:44Z ERROR librespot] could not initialize spirc: Permission denied { Login failed with reason: Bad credentials }
<exit 1>

$ ping ap-gue1.spotify.com
PING ap-gue1.spotify.com (34.158.253.218) 56(84) bytes of data.
64 bytes from 218.253.158.34.bc.googleusercontent.com (34.158.253.218): icmp_seq=1 ttl=60 time=121 ms
rgon commented 1 month ago

Do we have a way to block or force misbehaving APs? Given these logs, at least the following fail:

ap-gue1.spotify.com
ap-gew1.spotify.com
ap-gew4.spotify.com
ap-gae2.spotify.com

I tried the naive approach of pointing them to 127.0.0.1 in my /etc/hosts, but that triggers a connection error. Pointing them to another ap's IP also does not seem to do anything to avoid it.

roderickvd commented 1 month ago

Is it confirmed that other APs continue to work well?

It's not the first time that an AP starts misbehaving, but I don't remember this many. You could try pointing apresolve.spotify.com to 127.0.0.1 as it will force a fallback mechanism:

https://github.com/librespot-org/librespot/blob/299b7dec20b45b9fa19a4a46252079e8a8b7a8ba/core/src/apresolve.rs#L109

If you want to filter APs then you could do it in the same file, probably here:

https://github.com/librespot-org/librespot/blob/299b7dec20b45b9fa19a4a46252079e8a8b7a8ba/core/src/apresolve.rs#L64

But filtering that many could result in an empty set... don't you only get like three or something? So that should also make it resort to a fallback. No guarantees the fallback AP will work, although in the past it did.

Edit: misbehaving APs usually get fixed, sometimes in a few days, sometimes weeks. Not sure if this is a transitive failure on Spotify's end, or something that's really changing. That's why it would be good if someone had an old HW device with Connect to test, not something with recent firmware... to see if they're really phasing out this interface.

kingosticks commented 1 month ago

It appears to be for some users only. It's still working for me right now.

Probably it happens once your token expires

Yes, actually, I would have been using cached credentials (which don't expire). This session login failure is for the access point, it's not token based.

I've got a Windows 11 machine here today and no cached credentials. Both dev and master fail:

[2024-07-30T09:03:32Z INFO  librespot] librespot 0.4.2 6537c44 (Built on 2024-07-30, Build ID: EBl3oB2x, Profile: release)
[2024-07-30T09:03:32Z DEBUG librespot_discovery::server] Zeroconf server listening on 0.0.0.0:53805
[2024-07-30T09:03:32Z WARN  librespot_core::apresolve] Ignoring blacklisted access point ap-gue1.spotify.com:443
[2024-07-30T09:03:32Z WARN  librespot_core::apresolve] Ignoring blacklisted access point ap-gew4.spotify.com:80
[2024-07-30T09:03:32Z INFO  librespot_core::session] Connecting to AP "ap-gew1.spotify.com:443"
[2024-07-30T09:03:32Z ERROR librespot] Connection failed: Login failed with reason: Bad credentials
[2024-07-30T09:20:27Z INFO  librespot] librespot 0.5.0-dev 299b7de (Built on 2024-07-30, Build ID: Lts5Aikk, Profile: release)
[2024-07-30T09:20:27Z DEBUG librespot_core::session] new Session
[2024-07-30T09:20:27Z DEBUG librespot_discovery::server] Zeroconf server listening on 0.0.0.0:53991
[2024-07-30T09:20:27Z INFO  librespot_playback::mixer::softmixer] Mixing with softvol and volume control: Log(60.0)
[2024-07-30T09:20:27Z DEBUG librespot_connect::spirc] new Spirc[0]
[2024-07-30T09:20:27Z DEBUG librespot::component] new MercuryManager
[2024-07-30T09:20:27Z DEBUG librespot_playback::player] new Player [0]
[2024-07-30T09:20:27Z DEBUG librespot::component] new ApResolver
[2024-07-30T09:20:27Z INFO  librespot_playback::convert] Converting with ditherer: tpdf
[2024-07-30T09:20:27Z DEBUG librespot_core::http_client] Requesting https://apresolve.spotify.com/?type=accesspoint&type=dealer&type=spclient
[2024-07-30T09:20:27Z INFO  librespot_playback::audio_backend::rodio] Using Rodio sink with format S16 and cpal host: WASAPI
[2024-07-30T09:20:27Z INFO  librespot_playback::audio_backend::rodio] Using audio device: Headset Earphone (Poly BT600)
[2024-07-30T09:20:27Z DEBUG librespot_playback::audio_backend::rodio] Rodio sink was created
[2024-07-30T09:20:28Z INFO  librespot_core::session] Connecting to AP "ap-gew1.spotify.com:443"
[2024-07-30T09:20:28Z ERROR librespot] could not initialize spirc: Permission denied { Login failed with reason: Bad credentials }

I wonder if the one reported working Windows env above was also using cached creds? @azel1 can you provide a working log?

kingosticks commented 1 month ago

That's why it would be good if someone had an old HW device with Connect to test, not something with recent firmware... to see if they're really phasing out this interface.

They are phasing out the car thing in December. When Spotify started phasing out libspotify (their old official native library) they intermitently repeatedly broke lots of things in the run-up to turning it off. The theory was that they had no idea how the old and new parts of their systems depended on each other.

Does spotify-analyze still work? How can we observe the AP login these days?

SuisChan commented 1 month ago

Does spotify-analyze still work? How can we observe the AP login these days?

Idk, but on Windows you can use x64dbg to find 'shn_keys' or/and read the client's transmitted data

roderickvd commented 1 month ago

I think spotify-analyze needs on overhaul to make it work again. Have not used it in ages and I remember it was broken two years ago.

roderickvd commented 1 month ago

The theory was that they had no idea how the old and new parts of their systems depended on each other.

Yeah, nice that tribal development scheme.

microfx commented 1 month ago

so what's the workaround? Can I maybe switch to an app API key that authenticates my librespot? Librespot is crashing all the time due to this.

This happened even during playback / using librespot ... just crashed and then stopped being available

Connecting to AP "ap-gew4.spotify.com:4070"

roderickvd commented 1 month ago

That’s what we’re trying to find out. If you want to help, please read my posts to see what you can do to help nail it down.

Edit: as a kind reminder, I don’t use Spotify or even have an account anymore, so I’m here to give pointers and think along but it’s up to you guys.

noahhaon commented 1 month ago

It's not the first time that an AP starts misbehaving, but I don't remember this many. You could try pointing apresolve.spotify.com to 127.0.0.1 as it will force a fallback mechanism:

FWIW I tried this by modifying /etc/hosts and saw it trigger the fallback and got the same result :(

SuisChan commented 1 month ago

Anyway, does the latest spotify version (win, mac etc) connect to port 4070 or not anymore? (last time I checked, the only thing the client was sending to the server was information about listening events). (I don't have access to the desktop right now, but it's easy to check with Wireshark)

microfx commented 1 month ago
PING ap-gew4.spotify.com(131.0.158.34.bc.googleusercontent.com (64:ff9b::229e:83)) 56 data bytes
64 bytes from 131.0.158.34.bc.googleusercontent.com (64:ff9b::229e:83): icmp_seq=1 ttl=54 time=37.9 ms

telnet  ap-gew4.spotify.com 4070������������12:48
Trying 64:ff9b::229e:83...
Connected to ap-gew4.spotify.com.

does this help?! I will test macOS desktop client now

rgon commented 1 month ago

@bitclick

workaround: on another host without credentials its working fine via zeroconf / lan discovery

Can confirm local (without login) works(at least on master, librespot 0.0.0-dev 299b7de), so @microfx that's one possible workaround! Edit: if your use case can live without remote access, of course.

dspearson commented 1 month ago

Version 3.203.235

API-Change
Removed SpConnectionLoginPassword API.

My suspicion is that this is the cause.

See: https://developer.spotify.com/documentation/commercial-hardware/implementation/changelog (assuming this is using the Spotify Connect API)

roderickvd commented 1 month ago

Well there you seem to have it. Naive question but how would this impact the login5 approach?

kingosticks commented 1 month ago

The latest Linux client still connects to the AP on port 40070, you can get some verbose logging out their binary:

10:48:41.264 I [f:180 ] Resolved rpc host: https://gew1-spclient.spotify.com:443 10:48:41.264 I [f:180 ] Resolved streaming host: wss://gew1-dealer2.spotify.com:443 10:48:41.264 I [f:420 ] High request latency: https://apresolve.spotify.com/ took 160 ms 10:48:41.265 I [f:504 ] Connecting to AP ap-gew1.spotify.com:4070 10:48:41.273 I [f:59 ] Resolved ap-gew1.spotify.com to 104.199.65.124

I've kind of got spotify-analyse running on my WSL machine but annoyingly I can't catch the whole connection, the first thing I capture is ClientResponseEncrypted.

EDIT: I am being dumb, ClientResponseEncrypted is the interesting bit! It's using AUTHENTICATION_STORED_SPOTIFY_CREDENTIALS. I think login5 method is the answer. Their app doesn;t ask for your user and pass anymore, it does an oauth thing via your browser.

SuisChan commented 1 month ago

I can't catch the whole connection, the first thing I capture is ClientResponseEncrypted.

Isn't this normal behavior? In my case it always worked like that, I mean the first one intercepted was always ClientResponseEncrypted

kingosticks commented 1 month ago

I can't catch the whole connection, the first thing I capture is ClientResponseEncrypted.

Isn't this normal behavior? In my case it always worked like that, I mean the first one intercepted was always ClientResponseEncrypted

yeh sorry, I was being stupid. See edit.

dspearson commented 1 month ago

I guess a way to avoid this issue would be to use tokens a la https://github.com/librespot-org/librespot/issues/242 instead. My Rust is not really strong enough today to implement such a thing though unfortunately.

SuisChan commented 1 month ago

See edit.

Hmm, I see. It turns out the fix should be simple(?), login via login5 and then use the received stored credentials

rgon commented 1 month ago

@kingosticks I cannot log in on port 4070 either, with the same AP. Linux client.

librespot  | [2024-07-30T10:56:44Z INFO  librespot_core::session] Connecting to AP "ap-gew1.spotify.com:4070"
librespot  | [2024-07-30T10:56:44Z ERROR librespot] could not initialize spirc: Permission denied { Login failed with reason: Bad credentials }

This is not a windows/linux issue, but rather that the API change is being rolled out progressively, thus not affecting some combination of users/AP sometimes. Annoying to debug indeed...

kingosticks commented 1 month ago

So it's an Oauth flow for the first login and then stored creds afterwards. The description at https://developer.spotify.com/documentation/commercial-hardware/implementation/reference/3.203#spconnectionloginoauthtoken seems to support that.

eladyn commented 1 month ago

When I checked yesterday, while the desktop version uses OAuth for the login, the mobile (android) client still lets the user input their credentials (together with a hash cash challenge) and uses login5 to log in and get the stored credentials.

roderickvd commented 1 month ago

dev contains an implementation to solve the hash cash challenge that works most of the time. Sometimes it cannot solve it in the amount of time, and bails out. It’s not perfect but it works.

To trigger the hash cash, you must carefully set the right combination of OS and platform in various locations. I can’t tell you what the “right combination” is anymore but if you want it to work on Linux, then I do remember you have to look at the HTTP user agent in combination with the Mercury API key.

SuisChan commented 1 month ago

Sometimes it cannot solve it in the amount of time, and bails out

But it should always work, since it is reverse engineered from an original app, and the code should match

Also it may not solve the challenge in that time, if one use debug build, then yes, it may be slow

or...I don't know, there's not enough data to draw conclusions

devgianlu commented 1 month ago

I think they straight up removed the username password login method, for both the AP and Login5, as @dspearson mentioned. I tried the username password authentication with Login5 (which has always worked well in go-librespot) and it still fails.

This is supported by the fact that their own client doesn't let you enter credentials directly anymore, but just sends you to the website.

EDIT: Didn't read about the mobile client still supporting username and password, but that might be removed at some point too, perhaps the best idea is to just embrace the OAuth2 flow.

devgianlu commented 1 month ago

Did a quick implementation of the OAuth2 flow to replace username password authentication: https://github.com/devgianlu/go-librespot/commit/1e82a276812d5ef5ca0a52fe7d993ea549667a17

Seems to be working fine.

kingosticks commented 1 month ago

Awesome! OK so the flow is:

  1. Oauth prompt opened in user's web browser at accounts.spotify.com for oauth flow, user completes and code is returned to app
  2. Gets a client-token (can't remember how but we do this already)
  3. Exchange code for short-lived access token with POST https://accounts.spotify.com/api/token (using client-token header),
  4. Swap the temporary access token for stored credentials using Mercury ClientResponseEncrypted request of type AUTHENTICATION_SPOTIFY_TOKEN with our username and the auth_data is just the access token from step 3? Receives APWelcome response containing long-lived reusable_auth_credentials.
  5. All future logins (Mercury and login5) are using reusable creds. e.g. POST https://login5.spotify.com/v3/login (using client-token header) sending LoginRequest using stored_credential LoginRequest method.

Is that right @devgianlu ?

I did some of this in #1098 but I ran into problems when I tried to actually stream music. Was I just using the wrong oauth scopes ?!

p.s. for anyone else trying to mitm the linux client, I had to use /usr/bin/spotify --ignore-certificate-errors.

ejurgensen commented 1 month ago

OwnTone has an implementation Spotify's OAuth flow + stored credentials that might be a useful reference for you. See for instance login_token() in spotify_librespotc.c. Disregard the login() method, it isn't used, which also means OwnTone hasn't been affected by Spotify's change.