123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- use connection::{PlainConnection, CipherConnection};
- use keys::PrivateKeys;
- use librespot_protocol as protocol;
- use util;
- use crypto::sha1::Sha1;
- use crypto::digest::Digest;
- use protobuf::*;
- use rand::thread_rng;
- pub struct Config {
- pub application_key: Vec<u8>,
- pub user_agent: String,
- pub device_id: String,
- }
- pub struct Session {
- config: Config,
- connection: CipherConnection,
- }
- impl Session {
- pub fn new(mut config: Config) -> Session {
- config.device_id = {
- let mut h = Sha1::new();
- h.input_str(&config.device_id);
- h.result_str()
- };
- let keys = PrivateKeys::new();
- let mut connection = PlainConnection::connect().unwrap();
- let request = protobuf_init!(protocol::keyexchange::ClientHello::new(), {
- build_info => {
- product: protocol::keyexchange::Product::PRODUCT_LIBSPOTIFY_EMBEDDED,
- platform: protocol::keyexchange::Platform::PLATFORM_LINUX_X86,
- version: 0x10800000000,
- },
- /*
- fingerprints_supported => [
- protocol::keyexchange::Fingerprint::FINGERPRINT_GRAIN
- ],
- */
- cryptosuites_supported => [
- protocol::keyexchange::Cryptosuite::CRYPTO_SUITE_SHANNON,
- //protocol::keyexchange::Cryptosuite::CRYPTO_SUITE_RC4_SHA1_HMAC
- ],
- /*
- powschemes_supported => [
- protocol::keyexchange::Powscheme::POW_HASH_CASH
- ],
- */
- login_crypto_hello.diffie_hellman => {
- gc: keys.public_key(),
- server_keys_known: 1,
- },
- client_nonce: util::rand_vec(&mut thread_rng(), 0x10),
- padding: vec![0x1e],
- feature_set => {
- autoupdate2: true,
- }
- });
- let init_client_packet =
- connection.send_packet_prefix(&[0,4], &request.write_to_bytes().unwrap()).unwrap();
- let init_server_packet =
- connection.recv_packet().unwrap();
- let response : protocol::keyexchange::APResponseMessage =
- parse_from_bytes(&init_server_packet[4..]).unwrap();
- protobuf_bind!(response, {
- challenge => {
- login_crypto_challenge.diffie_hellman => {
- gs: remote_key,
- }
- }
- });
- let shared_keys = keys.add_remote_key(remote_key, &init_client_packet, &init_server_packet);
- let packet = protobuf_init!(protocol::keyexchange::ClientResponsePlaintext::new(), {
- login_crypto_response.diffie_hellman => {
- hmac: shared_keys.challenge().to_vec()
- },
- pow_response => {},
- crypto_response => {},
- });
- connection.send_packet(&packet.write_to_bytes().unwrap()).unwrap();
- Session {
- config: config,
- connection: connection.setup_cipher(shared_keys)
- }
- }
- pub fn login(&mut self, username: String, password: String) {
- let packet = protobuf_init!(protocol::authentication::ClientResponseEncrypted::new(), {
- login_credentials => {
- username: username,
- typ: protocol::authentication::Type::AUTHENTICATION_USER_PASS,
- auth_data: password.into_bytes(),
- },
- system_info => {
- cpu_family: protocol::authentication::CpuFamily::CPU_UNKNOWN,
- os: protocol::authentication::Os::OS_UNKNOWN,
- system_information_string: "librespot".to_string(),
- device_id: self.config.device_id.clone()
- },
- version_string: util::version::version_string(),
- appkey => {
- version: self.config.application_key[0] as u32,
- devkey: self.config.application_key[0x1..0x81].to_vec(),
- signature: self.config.application_key[0x81..0x141].to_vec(),
- useragent: self.config.user_agent.clone(),
- callback_hash: vec![0; 20],
- }
- });
- self.connection.send_encrypted_packet(
- 0xab,
- &packet.write_to_bytes().unwrap()).unwrap();
- loop {
- let (cmd, data) = self.connection.recv_packet().unwrap();
- println!("{:x}", cmd);
- }
- }
- }
|