1#![allow(renamed_and_removed_lints)]
37
38#[macro_use]
39extern crate error_chain;
40#[macro_use]
41extern crate serde_derive;
42extern crate crypto;
43extern crate serde;
44extern crate serde_json;
45
46use crypto::buffer::{ReadBuffer, WriteBuffer};
47use crypto::{aes, blockmodes, buffer};
48use std::fs::File;
49use std::io::Read;
50use std::collections::HashMap;
51
52use serde_json::{Value};
53
54const ACCOUNT_KEY: [u8; 16] = [1, 6, 4, 5, 2, 7, 4, 3, 12, 61, 14, 75, 254, 249, 212, 33]; #[derive(Debug, Default, Serialize, Deserialize)]
65pub struct JdAccountList(HashMap<String, Vec<JdAccount>>);
66
67#[derive(Debug, Default, Serialize, Deserialize)]
69pub struct JdAccount {
70 pub properties: Value,
71 pub hoster: String,
72 #[serde(rename = "maxSimultanDownloads")]
73 pub max_simultan_downloads: isize,
74 pub password : String,
75 #[serde(rename = "infoProperties")]
76 pub info_properties: Value,
77 #[serde(rename = "createTime")]
78 pub create_time: isize,
79 #[serde(rename = "trafficLeft")]
80 pub traffic_left: isize,
81 #[serde(rename = "trafficMax")]
82 pub traffic_max: isize,
83 #[serde(rename = "validUntil")]
84 pub valid_until: isize,
85 pub active: bool,
86 pub enabled: bool,
87 #[serde(rename = "trafficUnlimited")]
88 pub traffic_unlimited: bool,
89 pub specialtraffic: bool,
90 pub user: String,
91 #[serde(rename = "concurrentUsePossible")]
92 pub concurrent_use_possible: bool,
93 pub id: usize,
94 #[serde(rename = "errorType")]
95 pub error_type: Option<String>,
96 #[serde(rename = "errorString")]
97 pub error_string: Option<String>,
98}
99
100impl JdAccountList {
101 pub fn from_file<P: Into<String>>(path: P) -> Result<JdAccountList> {
103 let mut file = File::open(path.into())?;
105 let mut data = Vec::new();
106 file.read_to_end(&mut data)?;
107
108 JdAccountList::from_data(&data)
110 }
111
112 pub fn from_data(data: &[u8]) -> Result<JdAccountList> {
114 let mut data = decrypt_raw_data(data, &ACCOUNT_KEY, &ACCOUNT_KEY)?;
115
116 while data.last().ok_or("No decrypted data")? != &0x7Du8 {
118 data.pop().ok_or("No decrypted data in loop")?;
119 }
120
121 let data = std::str::from_utf8(&data)?;
123 let al: JdAccountList = serde_json::from_str(data)?;
124 Ok(al)
125 }
126
127 pub fn as_ref(&self) -> &HashMap<String, Vec<JdAccount>> {
129 &self.0
130 }
131}
132
133fn decrypt_raw_data(data: &[u8], key: &[u8], iv: &[u8]) -> Result<Vec<u8>> {
135 let mut decryptor = aes_cbc_decryptor(aes::KeySize::KeySize128, key, iv, blockmodes::NoPadding);
137
138 let mut buffer = [0; 4096];
140 let mut read_buffer = buffer::RefReadBuffer::new(data);
141 let mut writ_buffer = buffer::RefWriteBuffer::new(&mut buffer);
142 let mut result = Vec::new();
143
144 loop {
145 if decryptor
147 .decrypt(&mut read_buffer, &mut writ_buffer, true)
148 .is_err()
149 {
150 bail!("Can't decrypt");
151 }
152
153 if writ_buffer.is_empty() {
155 break;
156 }
157
158 result.extend_from_slice(writ_buffer.take_read_buffer().take_remaining());
160 }
161
162 result.retain(|x| *x != 0 as u8);
164
165 return Ok(result);
166}
167
168use crypto::aes::KeySize;
170use crypto::aessafe;
171use crypto::blockmodes::{CbcDecryptor, PaddingProcessor};
172use crypto::symmetriccipher::Decryptor;
173
174fn aes_cbc_decryptor<X: PaddingProcessor + Send + 'static>(
182 key_size: KeySize,
183 key: &[u8],
184 iv: &[u8],
185 padding: X,
186) -> Box<Decryptor + 'static> {
187 match key_size {
188 KeySize::KeySize128 => {
189 let aes_dec = aessafe::AesSafe128Decryptor::new(key);
190 let dec = Box::new(CbcDecryptor::new(aes_dec, padding, iv.to_vec()));
191 dec as Box<Decryptor + 'static>
192 }
193 KeySize::KeySize192 => {
194 let aes_dec = aessafe::AesSafe192Decryptor::new(key);
195 let dec = Box::new(CbcDecryptor::new(aes_dec, padding, iv.to_vec()));
196 dec as Box<Decryptor + 'static>
197 }
198 KeySize::KeySize256 => {
199 let aes_dec = aessafe::AesSafe256Decryptor::new(key);
200 let dec = Box::new(CbcDecryptor::new(aes_dec, padding, iv.to_vec()));
201 dec as Box<Decryptor + 'static>
202 }
203 }
204}
205
206error_chain!{
208
209 types {
210 Error, ErrorKind, ResultExt, Result;
211 }
212
213 foreign_links {
214 Fmt(::std::fmt::Error);
215 Io(::std::io::Error);
216 Utf8(::std::str::Utf8Error);
217 FromUtf8(::std::string::FromUtf8Error);
218 SerdeJson(::serde_json::Error);
219 }
220}