mirror of
https://github.com/librespot-org/librespot.git
synced 2024-11-08 16:45:43 +00:00
Report actual CPU, OS, platform and librespot version
This commit is contained in:
parent
f3bb679ab1
commit
4f51c1e810
5 changed files with 95 additions and 12 deletions
|
@ -108,7 +108,7 @@ fn initial_state() -> State {
|
|||
fn initial_device_state(config: ConnectConfig) -> DeviceState {
|
||||
{
|
||||
let mut msg = DeviceState::new();
|
||||
msg.set_sw_version(version::VERSION_STRING.to_string());
|
||||
msg.set_sw_version(version::SEMVER.to_string());
|
||||
msg.set_is_active(false);
|
||||
msg.set_can_play(true);
|
||||
msg.set_volume(0);
|
||||
|
|
|
@ -3,6 +3,7 @@ use hmac::{Hmac, Mac, NewMac};
|
|||
use protobuf::{self, Message};
|
||||
use rand::{thread_rng, RngCore};
|
||||
use sha1::Sha1;
|
||||
use std::env::consts::ARCH;
|
||||
use std::io;
|
||||
use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt};
|
||||
use tokio_util::codec::{Decoder, Framed};
|
||||
|
@ -10,7 +11,9 @@ use tokio_util::codec::{Decoder, Framed};
|
|||
use super::codec::ApCodec;
|
||||
use crate::diffie_hellman::DhLocalKeys;
|
||||
use crate::protocol;
|
||||
use crate::protocol::keyexchange::{APResponseMessage, ClientHello, ClientResponsePlaintext};
|
||||
use crate::protocol::keyexchange::{
|
||||
APResponseMessage, ClientHello, ClientResponsePlaintext, Platform, ProductFlags,
|
||||
};
|
||||
|
||||
pub async fn handshake<T: AsyncRead + AsyncWrite + Unpin>(
|
||||
mut connection: T,
|
||||
|
@ -42,13 +45,51 @@ where
|
|||
let mut client_nonce = vec![0; 0x10];
|
||||
thread_rng().fill_bytes(&mut client_nonce);
|
||||
|
||||
let platform = match std::env::consts::OS {
|
||||
"android" => Platform::PLATFORM_ANDROID_ARM,
|
||||
"freebsd" | "netbsd" | "openbsd" => match ARCH {
|
||||
"x86_64" => Platform::PLATFORM_FREEBSD_X86_64,
|
||||
_ => Platform::PLATFORM_FREEBSD_X86,
|
||||
},
|
||||
"ios" => match ARCH {
|
||||
"arm64" => Platform::PLATFORM_IPHONE_ARM64,
|
||||
_ => Platform::PLATFORM_IPHONE_ARM,
|
||||
},
|
||||
"linux" => match ARCH {
|
||||
"arm" | "arm64" => Platform::PLATFORM_LINUX_ARM,
|
||||
"blackfin" => Platform::PLATFORM_LINUX_BLACKFIN,
|
||||
"mips" => Platform::PLATFORM_LINUX_MIPS,
|
||||
"sh" => Platform::PLATFORM_LINUX_SH,
|
||||
"x86_64" => Platform::PLATFORM_LINUX_X86_64,
|
||||
_ => Platform::PLATFORM_LINUX_X86,
|
||||
},
|
||||
"macos" => match ARCH {
|
||||
"ppc" | "ppc64" => Platform::PLATFORM_OSX_PPC,
|
||||
"x86_64" => Platform::PLATFORM_OSX_X86_64,
|
||||
_ => Platform::PLATFORM_OSX_X86,
|
||||
},
|
||||
"windows" => match ARCH {
|
||||
"arm" => Platform::PLATFORM_WINDOWS_CE_ARM,
|
||||
"x86_64" => Platform::PLATFORM_WIN32_X86_64,
|
||||
_ => Platform::PLATFORM_WIN32_X86,
|
||||
},
|
||||
_ => Platform::PLATFORM_LINUX_X86,
|
||||
};
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
const PRODUCT_FLAGS: ProductFlags = ProductFlags::PRODUCT_FLAG_DEV_BUILD;
|
||||
#[cfg(not(debug_assertions))]
|
||||
const PRODUCT_FLAGS: ProductFlags = ProductFlags::PRODUCT_FLAG_NONE;
|
||||
|
||||
let mut packet = ClientHello::new();
|
||||
packet
|
||||
.mut_build_info()
|
||||
.set_product(protocol::keyexchange::Product::PRODUCT_PARTNER);
|
||||
.set_product(protocol::keyexchange::Product::PRODUCT_LIBSPOTIFY);
|
||||
packet
|
||||
.mut_build_info()
|
||||
.set_platform(protocol::keyexchange::Platform::PLATFORM_LINUX_X86);
|
||||
.mut_product_flags()
|
||||
.push(PRODUCT_FLAGS);
|
||||
packet.mut_build_info().set_platform(platform);
|
||||
packet.mut_build_info().set_version(999999999);
|
||||
packet
|
||||
.mut_cryptosuites_supported()
|
||||
|
|
|
@ -71,6 +71,29 @@ pub async fn authenticate(
|
|||
) -> Result<Credentials, AuthenticationError> {
|
||||
use crate::protocol::authentication::{APWelcome, ClientResponseEncrypted, CpuFamily, Os};
|
||||
|
||||
let cpu_family = match std::env::consts::ARCH {
|
||||
"blackfin" => CpuFamily::CPU_BLACKFIN,
|
||||
"arm" | "arm64" => CpuFamily::CPU_ARM,
|
||||
"ia64" => CpuFamily::CPU_IA64,
|
||||
"mips" => CpuFamily::CPU_MIPS,
|
||||
"ppc" => CpuFamily::CPU_PPC,
|
||||
"ppc64" => CpuFamily::CPU_PPC_64,
|
||||
"sh" => CpuFamily::CPU_SH,
|
||||
"x86" => CpuFamily::CPU_X86,
|
||||
"x86_64" => CpuFamily::CPU_X86_64,
|
||||
_ => CpuFamily::CPU_UNKNOWN,
|
||||
};
|
||||
|
||||
let os = match std::env::consts::OS {
|
||||
"android" => Os::OS_ANDROID,
|
||||
"freebsd" | "netbsd" | "openbsd" => Os::OS_FREEBSD,
|
||||
"ios" => Os::OS_IPHONE,
|
||||
"linux" => Os::OS_LINUX,
|
||||
"macos" => Os::OS_OSX,
|
||||
"windows" => Os::OS_WINDOWS,
|
||||
_ => Os::OS_UNKNOWN,
|
||||
};
|
||||
|
||||
let mut packet = ClientResponseEncrypted::new();
|
||||
packet
|
||||
.mut_login_credentials()
|
||||
|
@ -81,21 +104,19 @@ pub async fn authenticate(
|
|||
packet
|
||||
.mut_login_credentials()
|
||||
.set_auth_data(credentials.auth_data);
|
||||
packet
|
||||
.mut_system_info()
|
||||
.set_cpu_family(CpuFamily::CPU_UNKNOWN);
|
||||
packet.mut_system_info().set_os(Os::OS_UNKNOWN);
|
||||
packet.mut_system_info().set_cpu_family(cpu_family);
|
||||
packet.mut_system_info().set_os(os);
|
||||
packet
|
||||
.mut_system_info()
|
||||
.set_system_information_string(format!(
|
||||
"librespot_{}_{}",
|
||||
"librespot-{}-{}",
|
||||
version::SHA_SHORT,
|
||||
version::BUILD_ID
|
||||
));
|
||||
packet
|
||||
.mut_system_info()
|
||||
.set_device_id(device_id.to_string());
|
||||
packet.set_version_string(version::VERSION_STRING.to_string());
|
||||
packet.set_version_string(format!("librespot {}", version::SEMVER));
|
||||
|
||||
let cmd = PacketType::Login;
|
||||
let data = packet.write_to_bytes().unwrap();
|
||||
|
|
|
@ -5,9 +5,12 @@ use hyper::header::InvalidHeaderValue;
|
|||
use hyper::{Body, Client, Request, Response, StatusCode};
|
||||
use hyper_proxy::{Intercept, Proxy, ProxyConnector};
|
||||
use hyper_rustls::HttpsConnector;
|
||||
use std::env::consts::OS;
|
||||
use thiserror::Error;
|
||||
use url::Url;
|
||||
|
||||
use crate::version;
|
||||
|
||||
pub struct HttpClient {
|
||||
proxy: Option<Url>,
|
||||
}
|
||||
|
@ -50,11 +53,29 @@ impl HttpClient {
|
|||
|
||||
let connector = HttpsConnector::with_native_roots();
|
||||
|
||||
let spotify_version = match OS {
|
||||
"android" | "ios" => "8.6.84",
|
||||
_ => "117300517",
|
||||
};
|
||||
|
||||
let spotify_platform = match OS {
|
||||
"android" => "Android/31",
|
||||
"ios" => "iOS/15.1.1",
|
||||
"macos" => "OSX/0",
|
||||
"windows" => "Win32/0",
|
||||
_ => "Linux/0",
|
||||
};
|
||||
|
||||
let headers_mut = req.headers_mut();
|
||||
headers_mut.insert(
|
||||
"User-Agent",
|
||||
// Some features like lyrics are version-gated and require an official version string.
|
||||
HeaderValue::from_str("Spotify/8.6.80 iOS/13.5 (iPhone11,2)")?,
|
||||
HeaderValue::from_str(&format!(
|
||||
"Spotify/{} {} ({})",
|
||||
spotify_version,
|
||||
spotify_platform,
|
||||
version::VERSION_STRING
|
||||
))?,
|
||||
);
|
||||
|
||||
let response = if let Some(url) = &self.proxy {
|
||||
|
|
|
@ -57,7 +57,7 @@ impl RequestHandler {
|
|||
"status": 101,
|
||||
"statusString": "ERROR-OK",
|
||||
"spotifyError": 0,
|
||||
"version": "2.7.1",
|
||||
"version": crate::core::version::SEMVER,
|
||||
"deviceID": (self.config.device_id),
|
||||
"remoteName": (self.config.name),
|
||||
"activeUser": "",
|
||||
|
|
Loading…
Reference in a new issue