From 79fb65fbd89ee02bed8139aafb4bf55566ddf411 Mon Sep 17 00:00:00 2001 From: ejurgensen Date: Mon, 16 May 2022 23:28:18 +0200 Subject: [PATCH] [spotify] Fix for "Premium account required" (issue #1474) Sadly user-agent spoofing seems to be necessary after Spotify sunset of libspotify. Apparently librespot is whitelisted. --- src/inputs/librespot-c/README.md | 3 +++ src/inputs/librespot-c/src/connection.c | 16 +++++++++++----- src/inputs/librespot-c/tests/test1.c | 4 +--- src/inputs/spotify_librespotc.c | 5 +---- 4 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/inputs/librespot-c/README.md b/src/inputs/librespot-c/README.md index 330d55ef..4a254c21 100644 --- a/src/inputs/librespot-c/README.md +++ b/src/inputs/librespot-c/README.md @@ -1,3 +1,6 @@ +Limited C version of librespot. No Spotify Connect support. Library only. Used +by [OwnTone](https://github.com/owntone/owntone-server). + Build: - autoreconf -i && ./configure && make diff --git a/src/inputs/librespot-c/src/connection.c b/src/inputs/librespot-c/src/connection.c index aa41db9b..a65e6659 100644 --- a/src/inputs/librespot-c/src/connection.c +++ b/src/inputs/librespot-c/src/connection.c @@ -1033,6 +1033,9 @@ msg_make_client_response_encrypted(uint8_t *out, size_t out_len, struct sp_sessi ClientResponseEncrypted client_response = CLIENT_RESPONSE_ENCRYPTED__INIT; LoginCredentials login_credentials = LOGIN_CREDENTIALS__INIT; SystemInfo system_info = SYSTEM_INFO__INIT; + const char *client_name; + const char *client_version; + const char *client_build_id; char system_information_string[64]; char version_string[64]; ssize_t len; @@ -1061,18 +1064,21 @@ msg_make_client_response_encrypted(uint8_t *out, size_t out_len, struct sp_sessi else return -1; + // Note that Spotify seems to have whitelisting of client_name + client_name = (sp_sysinfo.client_name[0] != '\0') ? sp_sysinfo.client_name : "librespot"; + client_version = (sp_sysinfo.client_version[0] != '\0') ? sp_sysinfo.client_version : "000000"; + client_build_id = (sp_sysinfo.client_build_id[0] != '\0') ? sp_sysinfo.client_build_id : "0"; + snprintf(system_information_string, sizeof(system_information_string), "%s_%s_%s", client_name, client_version, client_build_id); + snprintf(version_string, sizeof(version_string), "%s-%s", client_name, client_version); + system_info.cpu_family = CPU_FAMILY__CPU_UNKNOWN; system_info.os = OS__OS_UNKNOWN; - snprintf(system_information_string, sizeof(system_information_string), "%s_%s_%s", - sp_sysinfo.client_name, sp_sysinfo.client_version, sp_sysinfo.client_build_id); system_info.system_information_string = system_information_string; system_info.device_id = sp_sysinfo.device_id; - - system_info_from_uname(&system_info); + system_info_from_uname(&system_info); // Sets cpu_family and os to actual values client_response.login_credentials = &login_credentials; client_response.system_info = &system_info; - snprintf(version_string, sizeof(version_string), "%s-%s", sp_sysinfo.client_name, sp_sysinfo.client_version); client_response.version_string = version_string; len = client_response_encrypted__get_packed_size(&client_response); diff --git a/src/inputs/librespot-c/tests/test1.c b/src/inputs/librespot-c/tests/test1.c index 4bd24bd7..011f0a09 100644 --- a/src/inputs/librespot-c/tests/test1.c +++ b/src/inputs/librespot-c/tests/test1.c @@ -258,9 +258,7 @@ main(int argc, char * argv[]) goto error; } - snprintf(sysinfo.client_name, sizeof(sysinfo.client_name), "myclient"); - snprintf(sysinfo.client_version, sizeof(sysinfo.client_version), "0.1"); - snprintf(sysinfo.client_build_id, sizeof(sysinfo.client_build_id), "a"); + memset(&sysinfo, 0, sizeof(struct sp_sysinfo)); snprintf(sysinfo.device_id, sizeof(sysinfo.device_id), "aabbccddeeff"); ret = librespotc_init(&sysinfo, &callbacks); diff --git a/src/inputs/spotify_librespotc.c b/src/inputs/spotify_librespotc.c index 3120bdc7..6e560ba5 100644 --- a/src/inputs/spotify_librespotc.c +++ b/src/inputs/spotify_librespotc.c @@ -304,7 +304,7 @@ struct sp_callbacks callbacks = { static int initialize(struct global_ctx *ctx) { - struct sp_sysinfo sysinfo; + struct sp_sysinfo sysinfo = { 0 }; cfg_t *spotify_cfg; int ret; @@ -316,9 +316,6 @@ initialize(struct global_ctx *ctx) if (ctx->is_initialized) return 0; - snprintf(sysinfo.client_name, sizeof(sysinfo.client_name), PACKAGE_NAME); - snprintf(sysinfo.client_version, sizeof(sysinfo.client_version), PACKAGE_VERSION); - snprintf(sysinfo.client_build_id, sizeof(sysinfo.client_build_id), "0"); snprintf(sysinfo.device_id, sizeof(sysinfo.device_id), "%" PRIx64, libhash); // TODO use a UUID instead ret = librespotc_init(&sysinfo, &callbacks);