spirc: Don’t hardcode stuff

This commit is contained in:
Paul Lietar 2015-07-02 01:27:19 +02:00
parent 45491925de
commit df11960946
4 changed files with 118 additions and 115 deletions

View file

@ -13,11 +13,11 @@ message ClientResponseEncrypted {
message LoginCredentials {
optional string username = 0xa;
required Type typ = 0x14;
required AuthenticationType typ = 0x14;
optional bytes auth_data = 0x1e;
}
enum Type {
enum AuthenticationType {
AUTHENTICATION_USER_PASS = 0x0;
AUTHENTICATION_STORED_SPOTIFY_CREDENTIALS = 0x1;
AUTHENTICATION_STORED_FACEBOOK_CREDENTIALS = 0x2;
@ -134,21 +134,31 @@ message ClientInfoFacebook {
optional string machine_id = 0x1;
}
message AuthSuccess {
required string username = 0x0a;
required uint32 data1 = 0x14;
required uint32 data2 = 0x19;
required uint32 data3 = 0x1e;
required bytes data4 = 0x28;
required bytes data5 = 0x32;
message APWelcome {
required string canonical_username = 0xa;
required AccountType account_type_logged_in = 0x14;
required AccountType credentials_type_logged_in = 0x19;
required AuthenticationType reusable_auth_credentials_type = 0x1e;
required bytes reusable_auth_credentials = 0x28;
optional bytes lfs_secret = 0x32;
optional AccountInfo account_info = 0x3c;
optional AccountInfoFacebook fb = 0x46;
}
message AuthFailure {
required uint32 code = 0x0a;
required Data1 data1 = 0x32;
message Data1 {
required string data0 = 0x01;
}
enum AccountType {
Spotify = 0x0;
Facebook = 0x1;
}
message AccountInfo {
optional AccountInfoSpotify spotify = 0x1;
optional AccountInfoFacebook facebook = 0x2;
}
message AccountInfoSpotify {
}
message AccountInfoFacebook {
optional string access_token = 0x1;
optional string machine_id = 0x2;
}

View file

@ -1,21 +1,21 @@
// size=80
message ClientHello {
required BuildInfo build_info = 0xa; // idx=0 offset=c
repeated Fingerprint fingerprints_supported = 0x14; // idx=ffff offset=10
repeated Cryptosuite cryptosuites_supported = 0x1e; // idx=ffff offset=2c
repeated Powscheme powschemes_supported = 0x28; // idx=ffff offset=48
required LoginCryptoHelloUnion login_crypto_hello = 0x32; // idx=1 offset=64
required bytes client_nonce = 0x3c; // idx=2 offset=68 size=f
optional bytes padding = 0x46; // idx=3 offset=78
optional FeatureSet feature_set = 0x50; // idx=4 offset=7c
required BuildInfo build_info = 0xa;
repeated Fingerprint fingerprints_supported = 0x14;
repeated Cryptosuite cryptosuites_supported = 0x1e;
repeated Powscheme powschemes_supported = 0x28;
required LoginCryptoHelloUnion login_crypto_hello = 0x32;
required bytes client_nonce = 0x3c;
optional bytes padding = 0x46;
optional FeatureSet feature_set = 0x50;
}
// size=38
message BuildInfo {
required Product product = 0xa; // idx=0 offset=c
repeated ProductFlags product_flags = 0x14; // idx=ffff offset=10
required Platform platform = 0x1e; // idx=1 offset=2c
required uint64 version = 0x28; // idx=2 offset=30 extra=246558
required Product product = 0xa;
repeated ProductFlags product_flags = 0x14;
required Platform platform = 0x1e;
required uint64 version = 0x28;
}
enum Product {
@ -72,108 +72,101 @@ enum Powscheme {
POW_HASH_CASH = 0x0;
}
// size=10
message LoginCryptoHelloUnion {
optional LoginCryptoDiffieHellmanHello diffie_hellman = 0xa; // idx=0 offset=c
optional LoginCryptoDiffieHellmanHello diffie_hellman = 0xa;
}
// size=70
message LoginCryptoDiffieHellmanHello {
required bytes gc = 0xa; // idx=0 offset=c size=5f
required uint32 server_keys_known = 0x14; // idx=1 offset=6c
required bytes gc = 0xa;
required uint32 server_keys_known = 0x14;
}
// size=10
message FeatureSet {
optional bool autoupdate2 = 0x1; // idx=0 offset=c
optional bool current_location = 0x2; // idx=1 offset=d
optional bool autoupdate2 = 0x1;
optional bool current_location = 0x2;
}
// size=18
message APResponseMessage {
optional APChallenge challenge = 0xa; // idx=0 offset=c
optional UpgradeRequiredMessage upgrade = 0x14; // idx=1 offset=10
optional APLoginFailed login_failed = 0x1e; // idx=2 offset=14
optional APChallenge challenge = 0xa;
optional UpgradeRequiredMessage upgrade = 0x14;
optional APLoginFailed login_failed = 0x1e;
}
// size=30
message APChallenge {
required LoginCryptoChallengeUnion login_crypto_challenge = 0xa; // idx=0 offset=c
required FingerprintChallengeUnion fingerprint_challenge = 0x14; // idx=1 offset=10
required PoWChallengeUnion pow_challenge = 0x1e; // idx=2 offset=14
required CryptoChallengeUnion crypto_challenge = 0x28; // idx=3 offset=18
required bytes server_nonce = 0x32; // idx=4 offset=1c size=f
optional bytes padding = 0x3c; // idx=5 offset=2c
required LoginCryptoChallengeUnion login_crypto_challenge = 0xa;
required FingerprintChallengeUnion fingerprint_challenge = 0x14;
required PoWChallengeUnion pow_challenge = 0x1e;
required CryptoChallengeUnion crypto_challenge = 0x28;
required bytes server_nonce = 0x32;
optional bytes padding = 0x3c;
}
// size=10
message LoginCryptoChallengeUnion {
optional LoginCryptoDiffieHellmanChallenge diffie_hellman = 0xa; // idx=0 offset=c
optional LoginCryptoDiffieHellmanChallenge diffie_hellman = 0xa;
}
// size=170
message LoginCryptoDiffieHellmanChallenge {
required bytes gs = 0xa; // idx=0 offset=c size=5f
required int32 server_signature_key = 0x14; // idx=1 offset=6c type=int8
required bytes gs_signature = 0x1e; // idx=2 offset=6d size=ff
required bytes gs = 0xa;
required int32 server_signature_key = 0x14;
required bytes gs_signature = 0x1e;
}
// size=14
message FingerprintChallengeUnion {
optional FingerprintGrainChallenge grain = 0xa; // idx=0 offset=c
optional FingerprintHmacRipemdChallenge hmac_ripemd = 0x14; // idx=1 offset=10
optional FingerprintGrainChallenge grain = 0xa;
optional FingerprintHmacRipemdChallenge hmac_ripemd = 0x14;
}
// size=1c
message FingerprintGrainChallenge {
required bytes kek = 0xa; // idx=0 offset=c size=f
required bytes kek = 0xa;
}
// size=20
message FingerprintHmacRipemdChallenge {
required bytes challenge = 0xa; // idx=0 offset=c size=13
required bytes challenge = 0xa;
}
// size=10
message PoWChallengeUnion {
optional PoWHashCashChallenge hash_cash = 0xa; // idx=0 offset=c
optional PoWHashCashChallenge hash_cash = 0xa;
}
// size=24
message PoWHashCashChallenge {
optional bytes prefix = 0xa; // idx=0 offset=c size=f
optional int32 length = 0x14; // idx=1 offset=1c type=int8
optional int32 target = 0x1e; // idx=2 offset=20
optional bytes prefix = 0xa;
optional int32 length = 0x14;
optional int32 target = 0x1e;
}
// size=14
message CryptoChallengeUnion {
optional CryptoShannonChallenge shannon = 0xa; // idx=0 offset=c
optional CryptoRc4Sha1HmacChallenge rc4_sha1_hmac = 0x14; // idx=1 offset=10
optional CryptoShannonChallenge shannon = 0xa;
optional CryptoRc4Sha1HmacChallenge rc4_sha1_hmac = 0x14;
}
// size=8
message CryptoShannonChallenge {
}
// size=8
message CryptoRc4Sha1HmacChallenge {
}
// size=18
message UpgradeRequiredMessage {
required bytes upgrade_signed_part = 0xa; // idx=0 offset=c
required bytes signature = 0x14; // idx=1 offset=10
optional string http_suffix = 0x1e; // idx=2 offset=14
required bytes upgrade_signed_part = 0xa;
required bytes signature = 0x14;
optional string http_suffix = 0x1e;
}
// size=1c
message APLoginFailed {
required ErrorCode error_code = 0xa; // idx=0 offset=c
optional int32 retry_delay = 0x14; // idx=1 offset=10
optional int32 expiry = 0x1e; // idx=2 offset=14
optional string error_description = 0x28; // idx=3 offset=18
required ErrorCode error_code = 0xa;
optional int32 retry_delay = 0x14;
optional int32 expiry = 0x1e;
optional string error_description = 0x28;
}
enum ErrorCode {
@ -190,50 +183,45 @@ enum ErrorCode {
ApplicationBanned = 0x11;
}
// size=18
message ClientResponsePlaintext {
required LoginCryptoResponseUnion login_crypto_response = 0xa; // idx=0 offset=c
required PoWResponseUnion pow_response = 0x14; // idx=1 offset=10
required CryptoResponseUnion crypto_response = 0x1e; // idx=2 offset=14
required LoginCryptoResponseUnion login_crypto_response = 0xa;
required PoWResponseUnion pow_response = 0x14;
required CryptoResponseUnion crypto_response = 0x1e;
}
// size=10
message LoginCryptoResponseUnion {
optional LoginCryptoDiffieHellmanResponse diffie_hellman = 0xa; // idx=0 offset=c
optional LoginCryptoDiffieHellmanResponse diffie_hellman = 0xa;
}
// size=20
message LoginCryptoDiffieHellmanResponse {
required bytes hmac = 0xa; // idx=0 offset=c size=13
required bytes hmac = 0xa;
}
// size=10
message PoWResponseUnion {
optional PoWHashCashResponse hash_cash = 0xa; // idx=0 offset=c
optional PoWHashCashResponse hash_cash = 0xa;
}
// size=1c
message PoWHashCashResponse {
required bytes hash_suffix = 0xa; // idx=0 offset=c size=f
required bytes hash_suffix = 0xa;
}
// size=14
message CryptoResponseUnion {
optional CryptoShannonResponse shannon = 0xa; // idx=0 offset=c
optional CryptoRc4Sha1HmacResponse rc4_sha1_hmac = 0x14; // idx=1 offset=10
optional CryptoShannonResponse shannon = 0xa;
optional CryptoRc4Sha1HmacResponse rc4_sha1_hmac = 0x14;
}
// size=10
message CryptoShannonResponse {
optional int32 dummy = 0x1; // idx=0 offset=c type=uint8
optional int32 dummy = 0x1;
}
// size=10
message CryptoRc4Sha1HmacResponse {
optional int32 dummy = 0x1; // idx=0 offset=c type=uint8
optional int32 dummy = 0x1;
}

View file

@ -44,6 +44,7 @@ use protobuf::core::Message;
use metadata::{MetadataCache, AlbumRef, ArtistRef, TrackRef};
use session::{Config, Session};
use util::SpotifyId;
use util::version::version_string;
use player::Player;
use mercury::{MercuryRequest, MercuryMethod};
use librespot_protocol as protocol;
@ -53,28 +54,31 @@ fn main() {
let mut appkey_file = File::open(Path::new(&args.next().unwrap())).unwrap();
let username = args.next().unwrap();
let password = args.next().unwrap();
let name = args.next().unwrap();
let mut appkey = Vec::new();
appkey_file.read_to_end(&mut appkey).unwrap();
let config = Config {
application_key: appkey,
user_agent: "ABC".to_string(),
device_id: "ABC".to_string()
user_agent: version_string(),
device_id: name.to_string()
};
let session = Session::new(config);
session.login(username, password);
session.login(username.clone(), password);
session.poll();
let ident = session.config.device_id.clone();
SpircManager{
session: session,
username: username.clone(),
name: name.clone(),
ident: ident,
device_type: 5,
state_update_id: 0,
seq_nr: 0,
name: "BlaBla".to_string(),
ident: ident,
device_type: 5,
volume: 0x8000,
can_play: true,
is_active: false,
@ -116,6 +120,7 @@ fn print_track(cache: &mut MetadataCache, track_id: SpotifyId) {
struct SpircManager {
session: Session,
username: String,
state_update_id: i64,
seq_nr: u32,
@ -135,7 +140,7 @@ impl SpircManager {
self.session.mercury.send(MercuryRequest{
method: MercuryMethod::SUB,
uri: "hm://remote/user/lietar/v23".to_string(),
uri: format!("hm://remote/user/{}/v23", self.username).to_string(),
content_type: None,
callback: Some(tx),
payload: Vec::new()
@ -185,7 +190,7 @@ impl SpircManager {
let device_state = self.device_state();
self.session.mercury.send(MercuryRequest{
method: MercuryMethod::SEND,
uri: "hm://remote/user/lietar".to_string(),
uri: format!("hm://remote/user/{}", self.username).to_string(),
content_type: None,
callback: None,
payload: vec![
@ -206,7 +211,7 @@ impl SpircManager {
fn device_state(&mut self) -> protocol::spirc::DeviceState {
protobuf_init!(protocol::spirc::DeviceState::new(), {
sw_version: "librespot-0.1.0".to_string(),
sw_version: version_string(),
is_active: self.is_active,
can_play: self.can_play,
volume: self.volume as u32,

View file

@ -147,7 +147,7 @@ impl Session {
let packet = protobuf_init!(protocol::authentication::ClientResponseEncrypted::new(), {
login_credentials => {
username: username,
typ: protocol::authentication::Type::AUTHENTICATION_USER_PASS,
typ: protocol::authentication::AuthenticationType::AUTHENTICATION_USER_PASS,
auth_data: password.into_bytes(),
},
system_info => {