Skip to content

Commit

Permalink
rustfmt
Browse files Browse the repository at this point in the history
  • Loading branch information
plietar committed Jan 2, 2016
1 parent 5464647 commit 90eeed3
Show file tree
Hide file tree
Showing 22 changed files with 380 additions and 342 deletions.
27 changes: 10 additions & 17 deletions src/audio_decrypt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,18 @@ use std::ops::Add;

use audio_key::AudioKey;

const AUDIO_AESIV : &'static [u8] = &[
0x72,0xe0,0x67,0xfb,0xdd,0xcb,0xcf,0x77,0xeb,0xe8,0xbc,0x64,0x3f,0x63,0x0d,0x93,
];
const AUDIO_AESIV: &'static [u8] = &[0x72, 0xe0, 0x67, 0xfb, 0xdd, 0xcb, 0xcf, 0x77, 0xeb, 0xe8,
0xbc, 0x64, 0x3f, 0x63, 0x0d, 0x93];

pub struct AudioDecrypt<T : io::Read> {
pub struct AudioDecrypt<T: io::Read> {
cipher: Box<SynchronousStreamCipher + 'static>,
key: AudioKey,
reader: T,
}

impl <T : io::Read> AudioDecrypt<T> {
impl<T: io::Read> AudioDecrypt<T> {
pub fn new(key: AudioKey, reader: T) -> AudioDecrypt<T> {
let cipher = aes::ctr(aes::KeySize::KeySize128,
&key,
AUDIO_AESIV);
let cipher = aes::ctr(aes::KeySize::KeySize128, &key, AUDIO_AESIV);
AudioDecrypt {
cipher: cipher,
key: key,
Expand All @@ -29,7 +26,7 @@ impl <T : io::Read> AudioDecrypt<T> {
}
}

impl <T : io::Read> io::Read for AudioDecrypt<T> {
impl<T: io::Read> io::Read for AudioDecrypt<T> {
fn read(&mut self, output: &mut [u8]) -> io::Result<usize> {
let mut buffer = vec![0u8; output.len()];
let len = try!(self.reader.read(&mut buffer));
Expand All @@ -40,17 +37,15 @@ impl <T : io::Read> io::Read for AudioDecrypt<T> {
}
}

impl <T : io::Read + io::Seek> io::Seek for AudioDecrypt<T> {
impl<T: io::Read + io::Seek> io::Seek for AudioDecrypt<T> {
fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
let newpos = try!(self.reader.seek(pos));
let skip = newpos % 16;

let iv = BigUint::from_bytes_be(AUDIO_AESIV)
.add(BigUint::from_u64(newpos / 16).unwrap())
.to_bytes_be();
self.cipher = aes::ctr(aes::KeySize::KeySize128,
&self.key,
&iv);
.add(BigUint::from_u64(newpos / 16).unwrap())
.to_bytes_be();
self.cipher = aes::ctr(aes::KeySize::KeySize128, &self.key, &iv);

let buf = vec![0u8; skip as usize];
let mut buf2 = vec![0u8; skip as usize];
Expand All @@ -59,5 +54,3 @@ impl <T : io::Read + io::Seek> io::Seek for AudioDecrypt<T> {
Ok(newpos as u64)
}
}


67 changes: 35 additions & 32 deletions src/audio_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ use util::{FileId, IgnoreExt, ZeroFile, mkdir_existing};
use session::Session;
use stream::StreamEvent;

const CHUNK_SIZE : usize = 0x20000;
const CHUNK_SIZE: usize = 0x20000;

pub enum AudioFile {
Direct(fs::File),
Loading(AudioFileLoading)
Loading(AudioFileLoading),
}

pub struct AudioFileLoading {
Expand All @@ -43,15 +43,18 @@ impl AudioFileLoading {
let read_file = files_iter.next().unwrap();
let mut write_file = files_iter.next().unwrap();

let size = session.stream(file_id, 0, 1).into_iter()
.filter_map(|event| {
match event {
StreamEvent::Header(id, ref data) if id == 0x3 => {
Some(BigEndian::read_u32(data) as usize * 4)
}
_ => None
}
}).next().unwrap();
let size = session.stream(file_id, 0, 1)
.into_iter()
.filter_map(|event| {
match event {
StreamEvent::Header(id, ref data) if id == 0x3 => {
Some(BigEndian::read_u32(data) as usize * 4)
}
_ => None,
}
})
.next()
.unwrap();

let chunk_count = (size + CHUNK_SIZE - 1) / CHUNK_SIZE;

Expand All @@ -70,22 +73,22 @@ impl AudioFileLoading {
let _shared = shared.clone();
let _session = session.clone();

thread::spawn(move || {
AudioFileLoading::fetch(&_session, _shared, write_file, seek_rx)
});
thread::spawn(move || AudioFileLoading::fetch(&_session, _shared, write_file, seek_rx));

AudioFileLoading {
read_file: read_file,

position: 0,
seek: seek_tx,

shared: shared
shared: shared,
}
}

fn fetch(session: &Session, shared: Arc<AudioFileShared>,
mut write_file: TempFile, seek_rx: mpsc::Receiver<u64>) {
fn fetch(session: &Session,
shared: Arc<AudioFileShared>,
mut write_file: TempFile,
seek_rx: mpsc::Receiver<u64>) {
let mut index = 0;

loop {
Expand Down Expand Up @@ -113,12 +116,14 @@ impl AudioFileLoading {
}
}

fn fetch_chunk(session: &Session, shared: &Arc<AudioFileShared>,
write_file: &mut TempFile, index: usize) {
fn fetch_chunk(session: &Session,
shared: &Arc<AudioFileShared>,
write_file: &mut TempFile,
index: usize) {

let rx = session.stream(shared.file_id,
(index * CHUNK_SIZE / 4) as u32,
(CHUNK_SIZE / 4) as u32);
(index * CHUNK_SIZE / 4) as u32,
(CHUNK_SIZE / 4) as u32);

println!("Chunk {}", index);

Expand All @@ -133,7 +138,7 @@ impl AudioFileLoading {

size += data.len();
if size >= CHUNK_SIZE {
break
break;
}
}
}
Expand All @@ -150,7 +155,8 @@ impl AudioFileLoading {

mkdir_existing(&AudioFileManager::cache_dir(session, shared.file_id)).unwrap();

let mut f = fs::File::create(AudioFileManager::cache_path(session, shared.file_id)).unwrap();
let mut f = fs::File::create(AudioFileManager::cache_path(session, shared.file_id))
.unwrap();
io::copy(write_file, &mut f).unwrap();
}
}
Expand All @@ -159,7 +165,7 @@ impl Read for AudioFileLoading {
fn read(&mut self, output: &mut [u8]) -> io::Result<usize> {
let index = self.position as usize / CHUNK_SIZE;
let offset = self.position as usize % CHUNK_SIZE;
let len = min(output.len(), CHUNK_SIZE-offset);
let len = min(output.len(), CHUNK_SIZE - offset);

let mut bitmap = self.shared.bitmap.lock().unwrap();
while !bitmap.contains(&index) {
Expand All @@ -179,11 +185,9 @@ impl Seek for AudioFileLoading {
fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
self.position = try!(self.read_file.seek(pos));

/*
* Notify the fetch thread to get the correct block
* This can fail if fetch thread has completed, in which case the
* block is ready. Just ignore the error.
*/
// Notify the fetch thread to get the correct block
// This can fail if fetch thread has completed, in which case the
// block is ready. Just ignore the error.
self.seek.send(self.position).ignore();
Ok(self.position as u64)
}
Expand Down Expand Up @@ -223,11 +227,10 @@ impl AudioFileManager {
AudioFileManager::cache_dir(session, file_id).join(&name[2..])
}

pub fn request (&mut self, session: &Session, file_id: FileId) -> AudioFile {
pub fn request(&mut self, session: &Session, file_id: FileId) -> AudioFile {
match fs::File::open(AudioFileManager::cache_path(session, file_id)) {
Ok(f) => AudioFile::Direct(f),
Err(..) => AudioFile::Loading(AudioFileLoading::new(session, file_id))
Err(..) => AudioFile::Loading(AudioFileLoading::new(session, file_id)),
}
}
}

69 changes: 36 additions & 33 deletions src/audio_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ struct AudioKeyId(SpotifyId, FileId);
enum AudioKeyStatus {
Loading(Vec<eventual::Complete<AudioKey, AudioKeyError>>),
Loaded(AudioKey),
Failed(AudioKeyError)
Failed(AudioKeyError),
}

pub struct AudioKeyManager {
next_seq: u32,
pending: HashMap<u32, AudioKeyId>,
pending: HashMap<u32, AudioKeyId>,
cache: HashMap<AudioKeyId, AudioKeyStatus>,
}

Expand All @@ -32,44 +32,48 @@ impl AudioKeyManager {
AudioKeyManager {
next_seq: 1,
pending: HashMap::new(),
cache: HashMap::new()
cache: HashMap::new(),
}
}

pub fn request(&mut self, session: &Session, track: SpotifyId, file: FileId)
-> eventual::Future<AudioKey, AudioKeyError> {
pub fn request(&mut self,
session: &Session,
track: SpotifyId,
file: FileId)
-> eventual::Future<AudioKey, AudioKeyError> {

let id = AudioKeyId(track, file);
self.cache.get_mut(&id).map(|status| match *status {
AudioKeyStatus::Failed(error) => {
eventual::Future::error(error)
}
AudioKeyStatus::Loaded(key) => {
eventual::Future::of(key)
}
AudioKeyStatus::Loading(ref mut req) => {
let (tx, rx) = eventual::Future::pair();
req.push(tx);
rx
}
}).unwrap_or_else(|| {
let seq = self.next_seq;
self.next_seq += 1;
self.cache
.get_mut(&id)
.map(|status| {
match *status {
AudioKeyStatus::Failed(error) => eventual::Future::error(error),
AudioKeyStatus::Loaded(key) => eventual::Future::of(key),
AudioKeyStatus::Loading(ref mut req) => {
let (tx, rx) = eventual::Future::pair();
req.push(tx);
rx
}
}
})
.unwrap_or_else(|| {
let seq = self.next_seq;
self.next_seq += 1;

let mut data : Vec<u8> = Vec::new();
data.write(&file.0).unwrap();
data.write(&track.to_raw()).unwrap();
data.write_u32::<BigEndian>(seq).unwrap();
data.write_u16::<BigEndian>(0x0000).unwrap();
let mut data: Vec<u8> = Vec::new();
data.write(&file.0).unwrap();
data.write(&track.to_raw()).unwrap();
data.write_u32::<BigEndian>(seq).unwrap();
data.write_u16::<BigEndian>(0x0000).unwrap();

session.send_packet(0xc, &data).unwrap();
session.send_packet(0xc, &data).unwrap();

self.pending.insert(seq, id.clone());
self.pending.insert(seq, id.clone());

let (tx, rx) = eventual::Future::pair();
self.cache.insert(id, AudioKeyStatus::Loading(vec!{ tx }));
rx
})
let (tx, rx) = eventual::Future::pair();
self.cache.insert(id, AudioKeyStatus::Loading(vec![tx]));
rx
})
}
}

Expand All @@ -78,7 +82,7 @@ impl PacketHandler for AudioKeyManager {
let mut data = Cursor::new(data);
let seq = data.read_u32::<BigEndian>().unwrap();

if let Some(status) = self.pending.remove(&seq).and_then(|id| { self.cache.get_mut(&id) }) {
if let Some(status) = self.pending.remove(&seq).and_then(|id| self.cache.get_mut(&id)) {
if cmd == 0xd {
let mut key = [0u8; 16];
data.read_exact(&mut key).unwrap();
Expand All @@ -103,4 +107,3 @@ impl PacketHandler for AudioKeyManager {
}
}
}

29 changes: 18 additions & 11 deletions src/authentication.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ fn read_u8<R: Read>(stream: &mut R) -> io::Result<u8> {
fn read_int<R: Read>(stream: &mut R) -> io::Result<u32> {
let lo = try!(read_u8(stream)) as u32;
if lo & 0x80 == 0 {
return Ok(lo)
return Ok(lo);
}

let hi = try!(read_u8(stream)) as u32;
Expand All @@ -40,7 +40,11 @@ fn read_bytes<R: Read>(stream: &mut R) -> io::Result<Vec<u8>> {
}

impl Session {
fn login(&self, username: String, auth_data: Vec<u8>, typ: AuthenticationType) -> Result<(), ()> {
fn login(&self,
username: String,
auth_data: Vec<u8>,
typ: AuthenticationType)
-> Result<(), ()> {
let packet = protobuf_init!(protocol::authentication::ClientResponseEncrypted::new(), {
login_credentials => {
username: username,
Expand Down Expand Up @@ -68,18 +72,18 @@ impl Session {
let (cmd, data) = self.recv();
match cmd {
0xac => {
let welcome_data : protocol::authentication::APWelcome =
let welcome_data: protocol::authentication::APWelcome =
protobuf::parse_from_bytes(&data).unwrap();
self.0.data.write().unwrap().canonical_username =
self.0.data.write().unwrap().canonical_username =
welcome_data.get_canonical_username().to_string();

eprintln!("Authenticated !");
Ok(())
}

0xad => {
let msg : protocol::keyexchange::APLoginFailed =
protobuf::parse_from_bytes(&data).unwrap();
let msg: protocol::keyexchange::APLoginFailed = protobuf::parse_from_bytes(&data)
.unwrap();
eprintln!("Authentication failed, {:?}", msg);
Err(())
}
Expand All @@ -91,7 +95,8 @@ impl Session {
}

pub fn login_password(&self, username: String, password: String) -> Result<(), ()> {
self.login(username, password.into_bytes(),
self.login(username,
password.into_bytes(),
AuthenticationType::AUTHENTICATION_USER_PASS)
}

Expand Down Expand Up @@ -121,14 +126,16 @@ impl Session {
let blob = {
// Anyone know what this block mode is ?
let mut data = vec![0u8; blob.len()];
let mut cipher = aes::ecb_decryptor(
aes::KeySize::KeySize192, &key, crypto::blockmodes::NoPadding);
let mut cipher = aes::ecb_decryptor(aes::KeySize::KeySize192,
&key,
crypto::blockmodes::NoPadding);
cipher.decrypt(&mut crypto::buffer::RefReadBuffer::new(&blob),
&mut crypto::buffer::RefWriteBuffer::new(&mut data),
true).unwrap();
true)
.unwrap();

let l = blob.len();
for i in 0..l-0x10 {
for i in 0..l - 0x10 {
data[l - i - 1] ^= data[l - i - 0x11];
}

Expand Down
Loading

0 comments on commit 90eeed3

Please sign in to comment.